Merge pull request #6 from FuegoFro/clean_up_your_train_view
Reorganize train info views and general code cleanup
This commit is contained in:
commit
4b8b7af55a
@ -17,6 +17,7 @@ import android.os.Handler;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.view.ActionMode;
|
import android.support.v7.view.ActionMode;
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
@ -48,6 +49,7 @@ import com.dougkeen.bart.services.EtdService;
|
|||||||
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
||||||
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
||||||
import com.dougkeen.bart.services.EtdService_;
|
import com.dougkeen.bart.services.EtdService_;
|
||||||
|
import com.dougkeen.util.Assert;
|
||||||
import com.dougkeen.util.Observer;
|
import com.dougkeen.util.Observer;
|
||||||
import com.dougkeen.util.WakeLocker;
|
import com.dougkeen.util.WakeLocker;
|
||||||
|
|
||||||
@ -86,8 +88,7 @@ public class ViewDeparturesActivity extends AppCompatActivity implements
|
|||||||
|
|
||||||
mProgress = (ProgressBar) findViewById(android.R.id.progress);
|
mProgress = (ProgressBar) findViewById(android.R.id.progress);
|
||||||
|
|
||||||
mDeparturesAdapter = new DepartureArrayAdapter(this,
|
mDeparturesAdapter = new DepartureArrayAdapter(this);
|
||||||
R.layout.departure_listing);
|
|
||||||
|
|
||||||
setListAdapter(mDeparturesAdapter);
|
setListAdapter(mDeparturesAdapter);
|
||||||
final ListView listView = getListView();
|
final ListView listView = getListView();
|
||||||
@ -127,9 +128,9 @@ public class ViewDeparturesActivity extends AppCompatActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
if (savedInstanceState.containsKey("departures")) {
|
Parcelable[] departuresArray = savedInstanceState.getParcelableArray("departures");
|
||||||
for (Parcelable departure : savedInstanceState
|
if (departuresArray != null) {
|
||||||
.getParcelableArray("departures")) {
|
for (Parcelable departure : departuresArray) {
|
||||||
mDeparturesAdapter.add((Departure) departure);
|
mDeparturesAdapter.add((Departure) departure);
|
||||||
}
|
}
|
||||||
mDeparturesAdapter.notifyDataSetChanged();
|
mDeparturesAdapter.notifyDataSetChanged();
|
||||||
@ -151,8 +152,9 @@ public class ViewDeparturesActivity extends AppCompatActivity implements
|
|||||||
}
|
}
|
||||||
refreshBoardedDeparture(false);
|
refreshBoardedDeparture(false);
|
||||||
|
|
||||||
getSupportActionBar().setHomeButtonEnabled(true);
|
ActionBar supportActionBar = Assert.notNull(getSupportActionBar());
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
supportActionBar.setHomeButtonEnabled(true);
|
||||||
|
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
if (bartRunnerApplication.shouldPlayAlarmRingtone()) {
|
if (bartRunnerApplication.shouldPlayAlarmRingtone()) {
|
||||||
soundTheAlarm();
|
soundTheAlarm();
|
||||||
@ -440,7 +442,7 @@ public class ViewDeparturesActivity extends AppCompatActivity implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mYourTrainSection.updateFromBoardedDeparture();
|
mYourTrainSection.updateFromBoardedDeparture(boardedDeparture);
|
||||||
|
|
||||||
if (currentVisibility != View.VISIBLE) {
|
if (currentVisibility != View.VISIBLE) {
|
||||||
showYourTrainSection(animate);
|
showYourTrainSection(animate);
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.dougkeen.bart.controls;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v7.widget.LinearLayoutCompat;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.Checkable;
|
||||||
|
|
||||||
|
import com.dougkeen.bart.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link android.widget.LinearLayout} that implements {@link Checkable} and changes
|
||||||
|
* its background color when checked.
|
||||||
|
*/
|
||||||
|
public class CheckableLinearLayout extends LinearLayoutCompat implements Checkable {
|
||||||
|
|
||||||
|
private boolean mChecked;
|
||||||
|
|
||||||
|
public CheckableLinearLayout(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckableLinearLayout(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChecked() {
|
||||||
|
return mChecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setChecked(boolean checked) {
|
||||||
|
mChecked = checked;
|
||||||
|
int colorRes = isChecked() ? R.color.blue_selection : android.R.color.transparent;
|
||||||
|
setBackgroundResource(colorRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toggle() {
|
||||||
|
setChecked(!isChecked());
|
||||||
|
}
|
||||||
|
}
|
@ -1,42 +0,0 @@
|
|||||||
package com.dougkeen.bart.controls;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.widget.Checkable;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
|
|
||||||
import com.dougkeen.bart.R;
|
|
||||||
|
|
||||||
public class DepartureListItemLayout extends RelativeLayout implements
|
|
||||||
Checkable {
|
|
||||||
|
|
||||||
public DepartureListItemLayout(Context context) {
|
|
||||||
super(context);
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.departure_listing, this,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean mChecked;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChecked() {
|
|
||||||
return mChecked;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setChecked(boolean checked) {
|
|
||||||
mChecked = checked;
|
|
||||||
if (isChecked()) {
|
|
||||||
setBackgroundDrawable(getContext().getResources().getDrawable(
|
|
||||||
R.color.blue_selection));
|
|
||||||
} else {
|
|
||||||
setBackgroundDrawable(getContext().getResources().getDrawable(
|
|
||||||
android.R.color.transparent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toggle() {
|
|
||||||
setChecked(!isChecked());
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,8 +10,7 @@ import android.widget.TextSwitcher;
|
|||||||
import com.dougkeen.bart.R;
|
import com.dougkeen.bart.R;
|
||||||
import com.dougkeen.bart.model.TextProvider;
|
import com.dougkeen.bart.model.TextProvider;
|
||||||
|
|
||||||
public class TimedTextSwitcher extends TextSwitcher implements
|
public class TimedTextSwitcher extends TextSwitcher implements Ticker.TickSubscriber {
|
||||||
Ticker.TickSubscriber {
|
|
||||||
|
|
||||||
public TimedTextSwitcher(Context context, AttributeSet attrs) {
|
public TimedTextSwitcher(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
@ -2,41 +2,51 @@ package com.dougkeen.bart.controls;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.GradientDrawable;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Checkable;
|
import android.widget.Checkable;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.dougkeen.bart.BartRunnerApplication;
|
|
||||||
import com.dougkeen.bart.R;
|
import com.dougkeen.bart.R;
|
||||||
import com.dougkeen.bart.model.Departure;
|
import com.dougkeen.bart.model.Departure;
|
||||||
import com.dougkeen.bart.model.TextProvider;
|
import com.dougkeen.bart.model.TextProvider;
|
||||||
import com.dougkeen.util.Observer;
|
import com.dougkeen.util.Observer;
|
||||||
|
|
||||||
public class YourTrainLayout extends RelativeLayout implements Checkable {
|
public class YourTrainLayout extends FrameLayout implements Checkable {
|
||||||
|
|
||||||
|
private final TextView destinationText;
|
||||||
|
private final TextView trainLength;
|
||||||
|
private final View colorBar;
|
||||||
|
private final ImageView bikeIcon;
|
||||||
|
private final View xferIcon;
|
||||||
|
private final CountdownTextView departureCountdown;
|
||||||
|
private final CountdownTextView arrivalCountdown;
|
||||||
|
private final TextView alarmText;
|
||||||
|
|
||||||
public YourTrainLayout(Context context) {
|
public YourTrainLayout(Context context) {
|
||||||
super(context);
|
this(context, null);
|
||||||
assignLayout(context);
|
}
|
||||||
|
|
||||||
|
public YourTrainLayout(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public YourTrainLayout(Context context, AttributeSet attrs, int defStyle) {
|
public YourTrainLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
assignLayout(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public YourTrainLayout(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
assignLayout(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assignLayout(Context context) {
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.your_train, this, true);
|
LayoutInflater.from(context).inflate(R.layout.your_train, this, true);
|
||||||
|
|
||||||
|
destinationText = (TextView) findViewById(R.id.yourTrainDestinationText);
|
||||||
|
trainLength = (TextView) findViewById(R.id.yourTrainTrainLengthText);
|
||||||
|
colorBar = findViewById(R.id.yourTrainDestinationColorBar);
|
||||||
|
bikeIcon = (ImageView) findViewById(R.id.yourTrainBikeIcon);
|
||||||
|
xferIcon = findViewById(R.id.yourTrainXferIcon);
|
||||||
|
departureCountdown = (CountdownTextView) findViewById(R.id.yourTrainDepartureCountdown);
|
||||||
|
arrivalCountdown = (CountdownTextView) findViewById(R.id.yourTrainArrivalCountdown);
|
||||||
|
alarmText = (TextView) findViewById(R.id.alarmText);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mChecked;
|
private boolean mChecked;
|
||||||
@ -75,13 +85,8 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setBackground() {
|
private void setBackground() {
|
||||||
if (isChecked()) {
|
int colorRes = isChecked() ? R.color.blue_selection : R.color.gray;
|
||||||
setBackgroundDrawable(getContext().getResources().getDrawable(
|
setBackgroundResource(colorRes);
|
||||||
R.color.blue_selection));
|
|
||||||
} else {
|
|
||||||
setBackgroundDrawable(getContext().getResources().getDrawable(
|
|
||||||
R.color.gray));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -89,11 +94,10 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
|
|||||||
setChecked(!isChecked());
|
setChecked(!isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFromBoardedDeparture() {
|
public void updateFromBoardedDeparture(final Departure boardedDeparture) {
|
||||||
final Departure boardedDeparture = ((BartRunnerApplication) ((Activity) getContext())
|
if (boardedDeparture == null) {
|
||||||
.getApplication()).getBoardedDeparture();
|
|
||||||
if (boardedDeparture == null)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!boardedDeparture.equals(mDeparture)) {
|
if (!boardedDeparture.equals(mDeparture)) {
|
||||||
if (mDeparture != null) {
|
if (mDeparture != null) {
|
||||||
@ -110,36 +114,23 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
|
|||||||
|
|
||||||
mDeparture = boardedDeparture;
|
mDeparture = boardedDeparture;
|
||||||
|
|
||||||
((TextView) findViewById(R.id.yourTrainDestinationText))
|
destinationText.setText(boardedDeparture.getTrainDestination().toString());
|
||||||
.setText(boardedDeparture.getTrainDestination().toString());
|
trainLength.setText(boardedDeparture.getTrainLengthAndPlatform());
|
||||||
|
|
||||||
((TextView) findViewById(R.id.yourTrainTrainLengthText))
|
colorBar.setBackgroundColor(boardedDeparture.getTrainDestinationColor());
|
||||||
.setText(boardedDeparture.getTrainLengthAndPlatform());
|
|
||||||
|
|
||||||
ImageView colorBar = (ImageView) findViewById(R.id.yourTrainDestinationColorBar);
|
|
||||||
((GradientDrawable) colorBar.getDrawable()).setColor(Color
|
|
||||||
.parseColor(boardedDeparture.getTrainDestinationColor()));
|
|
||||||
ImageView bikeIcon = (ImageView) findViewById(R.id.yourTrainBikeIcon);
|
|
||||||
if (boardedDeparture.isBikeAllowed()) {
|
if (boardedDeparture.isBikeAllowed()) {
|
||||||
bikeIcon.setImageDrawable(getResources().getDrawable(
|
bikeIcon.setImageResource(R.drawable.bike);
|
||||||
R.drawable.bike));
|
|
||||||
} else {
|
} else {
|
||||||
bikeIcon.setImageDrawable(getResources().getDrawable(
|
bikeIcon.setImageResource(R.drawable.nobike);
|
||||||
R.drawable.nobike));
|
|
||||||
}
|
}
|
||||||
if (boardedDeparture.getRequiresTransfer()) {
|
if (boardedDeparture.getRequiresTransfer()) {
|
||||||
findViewById(R.id.yourTrainXferIcon)
|
xferIcon.setVisibility(View.VISIBLE);
|
||||||
.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
} else {
|
||||||
findViewById(R.id.yourTrainXferIcon)
|
xferIcon.setVisibility(View.INVISIBLE);
|
||||||
.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAlarmIndicator();
|
updateAlarmIndicator();
|
||||||
|
|
||||||
CountdownTextView departureCountdown = (CountdownTextView) findViewById(R.id.yourTrainDepartureCountdown);
|
|
||||||
CountdownTextView arrivalCountdown = (CountdownTextView) findViewById(R.id.yourTrainArrivalCountdown);
|
|
||||||
|
|
||||||
final TextProvider textProvider = new TextProvider() {
|
final TextProvider textProvider = new TextProvider() {
|
||||||
@Override
|
@Override
|
||||||
public String getText(long tickNumber) {
|
public String getText(long tickNumber) {
|
||||||
@ -169,11 +160,10 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
|
|||||||
|
|
||||||
private void updateAlarmIndicator() {
|
private void updateAlarmIndicator() {
|
||||||
if (!mDeparture.isAlarmPending()) {
|
if (!mDeparture.isAlarmPending()) {
|
||||||
findViewById(R.id.alarmText).setVisibility(GONE);
|
alarmText.setVisibility(GONE);
|
||||||
} else {
|
} else {
|
||||||
findViewById(R.id.alarmText).setVisibility(VISIBLE);
|
alarmText.setVisibility(VISIBLE);
|
||||||
((TextView) findViewById(R.id.alarmText)).setText(String
|
alarmText.setText(String.valueOf(mDeparture.getAlarmLeadTimeMinutes()));
|
||||||
.valueOf(mDeparture.getAlarmLeadTimeMinutes()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
package com.dougkeen.bart.data;
|
package com.dougkeen.bart.data;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.content.res.Resources;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -21,65 +16,36 @@ import android.widget.ViewSwitcher.ViewFactory;
|
|||||||
|
|
||||||
import com.dougkeen.bart.R;
|
import com.dougkeen.bart.R;
|
||||||
import com.dougkeen.bart.controls.CountdownTextView;
|
import com.dougkeen.bart.controls.CountdownTextView;
|
||||||
import com.dougkeen.bart.controls.DepartureListItemLayout;
|
import com.dougkeen.bart.controls.CheckableLinearLayout;
|
||||||
import com.dougkeen.bart.controls.TimedTextSwitcher;
|
import com.dougkeen.bart.controls.TimedTextSwitcher;
|
||||||
import com.dougkeen.bart.model.Departure;
|
import com.dougkeen.bart.model.Departure;
|
||||||
import com.dougkeen.bart.model.TextProvider;
|
import com.dougkeen.bart.model.TextProvider;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
||||||
|
|
||||||
private Drawable noBikeDrawable;
|
private Drawable noBikeDrawable;
|
||||||
private Drawable bikeDrawable;
|
private Drawable bikeDrawable;
|
||||||
|
|
||||||
public DepartureArrayAdapter(Context context, int textViewResourceId,
|
@SuppressWarnings("deprecation")
|
||||||
Departure[] objects) {
|
public DepartureArrayAdapter(Context context) {
|
||||||
super(context, textViewResourceId, objects);
|
super(context, 0 /* resource, unused since we override getView */);
|
||||||
assignBikeDrawables();
|
Resources resources = context.getResources();
|
||||||
}
|
// We need to use the deprecated getDrawable since the newer version that
|
||||||
|
// replaces it was only made available in API 21.
|
||||||
private void assignBikeDrawables() {
|
noBikeDrawable = resources.getDrawable(R.drawable.nobike);
|
||||||
noBikeDrawable = getContext().getResources().getDrawable(
|
bikeDrawable = resources.getDrawable(R.drawable.bike);
|
||||||
R.drawable.nobike);
|
|
||||||
bikeDrawable = getContext().getResources().getDrawable(R.drawable.bike);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DepartureArrayAdapter(Context context, int resource,
|
|
||||||
int textViewResourceId, Departure[] objects) {
|
|
||||||
super(context, resource, textViewResourceId, objects);
|
|
||||||
assignBikeDrawables();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DepartureArrayAdapter(Context context, int resource,
|
|
||||||
int textViewResourceId, List<Departure> objects) {
|
|
||||||
super(context, resource, textViewResourceId, objects);
|
|
||||||
assignBikeDrawables();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DepartureArrayAdapter(Context context, int resource,
|
|
||||||
int textViewResourceId) {
|
|
||||||
super(context, resource, textViewResourceId);
|
|
||||||
assignBikeDrawables();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DepartureArrayAdapter(Context context, int textViewResourceId,
|
|
||||||
List<Departure> objects) {
|
|
||||||
super(context, textViewResourceId, objects);
|
|
||||||
assignBikeDrawables();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DepartureArrayAdapter(Context context, int textViewResourceId) {
|
|
||||||
super(context, textViewResourceId);
|
|
||||||
assignBikeDrawables();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
View view;
|
View view;
|
||||||
if (convertView != null
|
if (convertView != null && convertView instanceof CheckableLinearLayout) {
|
||||||
&& convertView instanceof DepartureListItemLayout) {
|
|
||||||
view = convertView;
|
view = convertView;
|
||||||
} else {
|
} else {
|
||||||
view = new DepartureListItemLayout(getContext());
|
view = LayoutInflater.from(getContext()).inflate(
|
||||||
|
R.layout.departure_listing, parent, false /* attachToRoot */);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Departure departure = getItem(position);
|
final Departure departure = getItem(position);
|
||||||
@ -132,10 +98,8 @@ public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageView colorBar = (ImageView) view
|
view.findViewById(R.id.destinationColorBar)
|
||||||
.findViewById(R.id.destinationColorBar);
|
.setBackgroundColor(departure.getTrainDestinationColor());
|
||||||
((GradientDrawable) colorBar.getDrawable()).setColor(Color
|
|
||||||
.parseColor(departure.getTrainDestinationColor()));
|
|
||||||
CountdownTextView countdownTextView = (CountdownTextView) view
|
CountdownTextView countdownTextView = (CountdownTextView) view
|
||||||
.findViewById(R.id.countdown);
|
.findViewById(R.id.countdown);
|
||||||
countdownTextView.setText(departure.getCountdownText());
|
countdownTextView.setText(departure.getCountdownText());
|
||||||
@ -179,11 +143,9 @@ public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
|||||||
bikeIcon.setImageDrawable(noBikeDrawable);
|
bikeIcon.setImageDrawable(noBikeDrawable);
|
||||||
}
|
}
|
||||||
if (departure.getRequiresTransfer()) {
|
if (departure.getRequiresTransfer()) {
|
||||||
view.findViewById(R.id.xferIcon)
|
view.findViewById(R.id.xferIcon).setVisibility(View.VISIBLE);
|
||||||
.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
} else {
|
||||||
view.findViewById(R.id.xferIcon)
|
view.findViewById(R.id.xferIcon).setVisibility(View.INVISIBLE);
|
||||||
.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
package com.dougkeen.bart.model;
|
package com.dougkeen.bart.model;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.ColorInt;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.NotificationCompat.Builder;
|
import android.support.v4.app.NotificationCompat.Builder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -23,6 +19,12 @@ import com.dougkeen.bart.activities.ViewDeparturesActivity;
|
|||||||
import com.dougkeen.bart.services.BoardedDepartureService;
|
import com.dougkeen.bart.services.BoardedDepartureService;
|
||||||
import com.dougkeen.util.Observable;
|
import com.dougkeen.util.Observable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
public class Departure implements Parcelable, Comparable<Departure> {
|
public class Departure implements Parcelable, Comparable<Departure> {
|
||||||
private static final int MINIMUM_MERGE_OVERLAP_MILLIS = 5000;
|
private static final int MINIMUM_MERGE_OVERLAP_MILLIS = 5000;
|
||||||
private static final int EXPIRE_MINUTES_AFTER_ARRIVAL = 1;
|
private static final int EXPIRE_MINUTES_AFTER_ARRIVAL = 1;
|
||||||
@ -133,8 +135,9 @@ public class Departure implements Parcelable, Comparable<Departure> {
|
|||||||
this.line = line;
|
this.line = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTrainDestinationColor() {
|
@ColorInt
|
||||||
return destinationColor;
|
public int getTrainDestinationColor() {
|
||||||
|
return Color.parseColor(destinationColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTrainDestinationColor(String destinationColor) {
|
public void setTrainDestinationColor(String destinationColor) {
|
||||||
@ -627,33 +630,36 @@ public class Departure implements Parcelable, Comparable<Departure> {
|
|||||||
final Intent cancelAlarmIntent = new Intent(context,
|
final Intent cancelAlarmIntent = new Intent(context,
|
||||||
BoardedDepartureService.class);
|
BoardedDepartureService.class);
|
||||||
cancelAlarmIntent.putExtra("cancelNotifications", true);
|
cancelAlarmIntent.putExtra("cancelNotifications", true);
|
||||||
|
String title = getOrigin().shortName + " to " + getPassengerDestination().shortName;
|
||||||
|
|
||||||
Builder notificationBuilder = new NotificationCompat.Builder(context)
|
Builder notificationBuilder = new NotificationCompat.Builder(context)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.setSmallIcon(R.drawable.ic_stat_notification)
|
.setSmallIcon(R.drawable.ic_stat_notification)
|
||||||
.setContentTitle(
|
.setContentTitle(title)
|
||||||
getOrigin().shortName + " to "
|
|
||||||
+ getPassengerDestination().shortName)
|
|
||||||
.setContentIntent(getNotificationIntent(context)).setWhen(0);
|
.setContentIntent(getNotificationIntent(context)).setWhen(0);
|
||||||
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 16) {
|
if (android.os.Build.VERSION.SDK_INT >= 16) {
|
||||||
notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH)
|
notificationBuilder
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
.setContentText(minutesText + " until departure");
|
.setContentText(minutesText + " until departure");
|
||||||
|
|
||||||
if (isAlarmPending()) {
|
if (isAlarmPending()) {
|
||||||
notificationBuilder.addAction(
|
PendingIntent pendingIntent = PendingIntent.getService(
|
||||||
R.drawable.ic_action_cancel_alarm,
|
context, 0, cancelAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
"Cancel alarm",
|
String subText = "Alarm " + getAlarmLeadTimeMinutes() + " minutes before departure";
|
||||||
PendingIntent.getService(context, 0, cancelAlarmIntent,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT)).setSubText(
|
notificationBuilder
|
||||||
"Alarm " + getAlarmLeadTimeMinutes()
|
.addAction(R.drawable.ic_action_cancel_alarm, "Cancel alarm", pendingIntent)
|
||||||
+ " minutes before departure");
|
.setSubText(subText);
|
||||||
}
|
}
|
||||||
} else if (isAlarmPending()) {
|
} else if (isAlarmPending()) {
|
||||||
notificationBuilder.setContentText(minutesText
|
String text = minutesText
|
||||||
+ " to departure (alarm at " + getAlarmLeadTimeMinutes()
|
+ " to departure (alarm at " + getAlarmLeadTimeMinutes()
|
||||||
+ " min" + ((getAlarmLeadTimeMinutes() == 1) ? "" : "s")
|
+ " min" + ((getAlarmLeadTimeMinutes() == 1) ? "" : "s")
|
||||||
+ ")");
|
+ ")";
|
||||||
|
notificationBuilder.setContentText(text);
|
||||||
} else {
|
} else {
|
||||||
notificationBuilder
|
notificationBuilder.setContentText(minutesText + " until departure");
|
||||||
.setContentText(minutesText + " until departure");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return notificationBuilder.build();
|
return notificationBuilder.build();
|
||||||
|
@ -4,7 +4,6 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -15,6 +14,7 @@ import android.os.HandlerThread;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.support.v4.app.NotificationManagerCompat;
|
||||||
|
|
||||||
import com.dougkeen.bart.BartRunnerApplication;
|
import com.dougkeen.bart.BartRunnerApplication;
|
||||||
import com.dougkeen.bart.model.Departure;
|
import com.dougkeen.bart.model.Departure;
|
||||||
@ -34,7 +34,7 @@ public class BoardedDepartureService extends Service implements
|
|||||||
private boolean mBound = false;
|
private boolean mBound = false;
|
||||||
private EtdService mEtdService;
|
private EtdService mEtdService;
|
||||||
private StationPair mStationPair;
|
private StationPair mStationPair;
|
||||||
private NotificationManager mNotificationManager;
|
private NotificationManagerCompat mNotificationManager;
|
||||||
private AlarmManager mAlarmManager;
|
private AlarmManager mAlarmManager;
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
private boolean mHasShutDown = false;
|
private boolean mHasShutDown = false;
|
||||||
@ -91,7 +91,7 @@ public class BoardedDepartureService extends Service implements
|
|||||||
|
|
||||||
bindService(EtdService_.intent(this).get(), mConnection,
|
bindService(EtdService_.intent(this).get(), mConnection,
|
||||||
Context.BIND_AUTO_CREATE);
|
Context.BIND_AUTO_CREATE);
|
||||||
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
mNotificationManager = NotificationManagerCompat.from(this);
|
||||||
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||||
mHandler = new Handler();
|
mHandler = new Handler();
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
@ -302,8 +302,7 @@ public class BoardedDepartureService extends Service implements
|
|||||||
.getBoardedDeparture();
|
.getBoardedDeparture();
|
||||||
if (boardedDeparture != null) {
|
if (boardedDeparture != null) {
|
||||||
mNotificationManager.notify(DEPARTURE_NOTIFICATION_ID,
|
mNotificationManager.notify(DEPARTURE_NOTIFICATION_ID,
|
||||||
boardedDeparture
|
boardedDeparture.createNotification(getApplicationContext()));
|
||||||
.createNotification(getApplicationContext()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
app/src/main/java/com/dougkeen/util/Assert.java
Normal file
13
app/src/main/java/com/dougkeen/util/Assert.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package com.dougkeen.util;
|
||||||
|
|
||||||
|
public final class Assert {
|
||||||
|
// Uninstantiable
|
||||||
|
private Assert() {}
|
||||||
|
|
||||||
|
public static <T> T notNull(T obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
throw new AssertionError("Expected object to be non-null");
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
@ -1,77 +1,111 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<merge
|
<com.dougkeen.bart.controls.CheckableLinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:bart="http://schemas.android.com/apk/res-auto"
|
xmlns:bart="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent">
|
android:layout_height="fill_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
>
|
||||||
|
|
||||||
<ImageView
|
<!-- This layout is used when the height is >= 480 dp, eg usually in portrait mode. -->
|
||||||
|
|
||||||
|
<View
|
||||||
android:id="@+id/destinationColorBar"
|
android:id="@+id/destinationColorBar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="15dp"
|
||||||
android:layout_height="64dp"
|
android:layout_height="64dp"
|
||||||
android:layout_alignParentLeft="true"
|
tools:background="#F00"
|
||||||
android:layout_centerVertical="true"
|
/>
|
||||||
android:src="@drawable/basic_rectangle" />
|
|
||||||
|
|
||||||
|
<!-- Holds the destination, the train info, and the arrival time -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/topRow"
|
android:layout_width="0dp"
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_marginLeft="5dp"
|
||||||
android:layout_toRightOf="@id/destinationColorBar">
|
android:layout_marginRight="5dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/destinationText"
|
android:id="@+id/destinationText"
|
||||||
style="@style/DepartureDestinationText"
|
style="@style/DepartureDestinationText"
|
||||||
android:layout_weight="1"
|
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:singleLine="true" />
|
android:singleLine="true"
|
||||||
|
tools:text="Richmond"
|
||||||
<ImageView
|
/>
|
||||||
android:id="@+id/bikeIcon"
|
|
||||||
style="@style/BikeIcon" />
|
|
||||||
|
|
||||||
<com.dougkeen.bart.controls.CountdownTextView
|
|
||||||
android:id="@+id/countdown"
|
|
||||||
style="@style/DepartureCountdownText"
|
|
||||||
android:gravity="right"
|
|
||||||
android:width="90dp"
|
|
||||||
bart:tickInterval="1" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/xferIcon"
|
|
||||||
style="@style/XferIcon"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_below="@id/topRow"
|
|
||||||
android:src="@drawable/xfer" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/trainLengthText"
|
android:id="@+id/trainLengthText"
|
||||||
style="@style/DepartureUncertaintyText"
|
style="@style/DepartureUncertaintyText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/topRow"
|
tools:text="9 cars, platform 2"
|
||||||
android:layout_toRightOf="@id/destinationColorBar" />
|
/>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/uncertainty"
|
|
||||||
style="@style/DepartureUncertaintyText"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_below="@id/topRow" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/estimatedArrival"
|
android:id="@+id/estimatedArrival"
|
||||||
style="@style/DepartureUncertaintyText"
|
style="@style/DepartureUncertaintyText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/trainLengthText"
|
tools:text="Arrives ~11:12 AM (20 mins)"
|
||||||
android:layout_toRightOf="@id/destinationColorBar" />
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Holds the bike and xfer icons -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/bikeIcon"
|
||||||
|
style="@style/TrainInfoIcon"
|
||||||
|
tools:src="@drawable/bike"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/xferIcon"
|
||||||
|
style="@style/TrainInfoIcon"
|
||||||
|
android:src="@drawable/xfer"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Holds the departure countdown, uncertainty, and departure time -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="5dp"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
|
android:gravity="right"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
|
||||||
|
<com.dougkeen.bart.controls.CountdownTextView
|
||||||
|
android:id="@+id/countdown"
|
||||||
|
style="@style/DepartureCountdownText"
|
||||||
|
android:width="90dp"
|
||||||
|
android:gravity="right"
|
||||||
|
bart:tickInterval="1"
|
||||||
|
tools:text="9m, 57s"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/uncertainty"
|
||||||
|
style="@style/DepartureUncertaintyText"
|
||||||
|
tools:text="(+8s)"
|
||||||
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/departureTime"
|
android:id="@+id/departureTime"
|
||||||
style="@style/DepartureUncertaintyText"
|
style="@style/DepartureUncertaintyText"
|
||||||
android:layout_alignParentRight="true"
|
tools:text="11:20 AM"
|
||||||
android:layout_below="@id/uncertainty" />
|
/>
|
||||||
|
|
||||||
</merge>
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.dougkeen.bart.controls.CheckableLinearLayout>
|
||||||
|
@ -1,64 +1,98 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<merge
|
<com.dougkeen.bart.controls.CheckableLinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:bart="http://schemas.android.com/apk/res-auto"
|
xmlns:bart="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent">
|
android:layout_height="fill_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
>
|
||||||
|
|
||||||
<ImageView
|
<!-- This layout is used when the height is less than 480 dp (eg usually in landscape mode) -->
|
||||||
|
|
||||||
|
<View
|
||||||
android:id="@+id/destinationColorBar"
|
android:id="@+id/destinationColorBar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="15dp"
|
||||||
android:layout_height="45dp"
|
android:layout_height="45dp"
|
||||||
android:layout_alignParentLeft="true"
|
tools:background="#F00"
|
||||||
android:layout_centerVertical="true"
|
/>
|
||||||
android:src="@drawable/basic_rectangle" />
|
|
||||||
|
|
||||||
|
<!-- Holds destination and train info/arrival -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/topRow"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_marginLeft="5dp"
|
||||||
android:layout_toRightOf="@id/destinationColorBar">
|
android:layout_marginRight="5dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/destinationText"
|
android:id="@+id/destinationText"
|
||||||
style="@style/DepartureDestinationText"
|
style="@style/DepartureDestinationText"
|
||||||
android:layout_weight="1"
|
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:singleLine="true" />
|
android:singleLine="true"
|
||||||
|
tools:text="Richmond"
|
||||||
<ImageView
|
/>
|
||||||
android:id="@+id/bikeIcon"
|
|
||||||
style="@style/BikeIcon" />
|
|
||||||
|
|
||||||
<com.dougkeen.bart.controls.CountdownTextView
|
|
||||||
android:id="@+id/countdown"
|
|
||||||
style="@style/DepartureCountdownText"
|
|
||||||
android:gravity="right"
|
|
||||||
android:width="90dp"
|
|
||||||
bart:tickInterval="1" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/xferIcon"
|
|
||||||
style="@style/XferIcon"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_below="@id/topRow"
|
|
||||||
android:src="@drawable/xfer" />
|
|
||||||
|
|
||||||
<com.dougkeen.bart.controls.TimedTextSwitcher
|
<com.dougkeen.bart.controls.TimedTextSwitcher
|
||||||
android:id="@+id/trainLengthText"
|
android:id="@+id/trainLengthText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/topRow"
|
bart:tickInterval="1"
|
||||||
android:layout_toRightOf="@id/destinationColorBar"
|
tools:text="9 cars, platform 2"
|
||||||
bart:tickInterval="1" />
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Holds bike and xfer icons -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/bikeIcon"
|
||||||
|
style="@style/TrainInfoIcon"
|
||||||
|
tools:src="@drawable/bike"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/xferIcon"
|
||||||
|
style="@style/TrainInfoIcon"
|
||||||
|
android:src="@drawable/xfer"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Holds departure countdown and uncertainty/departure time-->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="5dp"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
|
android:gravity="right"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
|
||||||
|
<com.dougkeen.bart.controls.CountdownTextView
|
||||||
|
android:id="@+id/countdown"
|
||||||
|
style="@style/DepartureCountdownText"
|
||||||
|
android:width="90dp"
|
||||||
|
android:gravity="right"
|
||||||
|
bart:tickInterval="1"
|
||||||
|
tools:text="9m, 57s"
|
||||||
|
/>
|
||||||
|
|
||||||
<com.dougkeen.bart.controls.TimedTextSwitcher
|
<com.dougkeen.bart.controls.TimedTextSwitcher
|
||||||
android:id="@+id/uncertainty"
|
android:id="@+id/uncertainty"
|
||||||
style="@style/DepartureUncertaintyText"
|
style="@style/DepartureUncertaintyText"
|
||||||
android:layout_alignParentRight="true"
|
bart:tickInterval="1"
|
||||||
android:layout_below="@id/topRow"
|
tools:text="(+8s)"
|
||||||
bart:tickInterval="1" />
|
/>
|
||||||
|
|
||||||
</merge>
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.dougkeen.bart.controls.CheckableLinearLayout>
|
||||||
|
@ -1,82 +1,121 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<merge
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:bart="http://schemas.android.com/apk/res-auto" >
|
xmlns:bart="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
<TextView
|
|
||||||
android:id="@+id/alarmText"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentRight="true"
|
android:orientation="vertical"
|
||||||
android:layout_alignParentTop="true"
|
>
|
||||||
android:drawableLeft="@drawable/ic_action_alarm"
|
|
||||||
android:gravity="center_vertical"
|
<!-- Holds the "Your Train" title and the alarm indicator -->
|
||||||
android:textSize="16dp"
|
<FrameLayout
|
||||||
android:visibility="gone"></TextView>
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/yourTrainHeader"
|
android:id="@+id/yourTrainHeader"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_gravity="center_horizontal"
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:text="@string/your_train"
|
android:text="@string/your_train"
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
android:textSize="20dp"
|
android:textSize="20dp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold"
|
||||||
|
/>
|
||||||
|
|
||||||
<ImageView
|
<TextView
|
||||||
android:id="@+id/yourTrainDestinationColorBar"
|
android:id="@+id/alarmText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="right"
|
||||||
|
android:drawableLeft="@drawable/ic_action_alarm"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="16dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:text="5"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<!-- Holds the color bar, destination text, train info, bike icon, and xfer icon -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/yourTrainDestinationColorBar"
|
||||||
|
android:layout_width="15dp"
|
||||||
android:layout_height="45dp"
|
android:layout_height="45dp"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_below="@id/yourTrainHeader"
|
tools:background="#F00"
|
||||||
android:src="@drawable/basic_rectangle" />
|
/>
|
||||||
|
|
||||||
|
<!-- Holds the destination text and train info -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="5dp"
|
||||||
|
>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/yourTrainDestinationText"
|
android:id="@+id/yourTrainDestinationText"
|
||||||
style="@style/DepartureDestinationText"
|
style="@style/DepartureDestinationText"
|
||||||
android:layout_below="@id/yourTrainHeader"
|
|
||||||
android:layout_toRightOf="@id/yourTrainDestinationColorBar"
|
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:singleLine="true" />
|
android:singleLine="true"
|
||||||
|
tools:text="Richmond"
|
||||||
<ImageView
|
/>
|
||||||
android:id="@+id/yourTrainBikeIcon"
|
|
||||||
style="@style/BikeIcon"
|
|
||||||
android:layout_below="@id/yourTrainHeader"
|
|
||||||
android:layout_toRightOf="@id/yourTrainDestinationText" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/yourTrainXferIcon"
|
|
||||||
style="@style/XferIcon"
|
|
||||||
android:layout_below="@id/yourTrainBikeIcon"
|
|
||||||
android:layout_toRightOf="@id/yourTrainDestinationText"
|
|
||||||
android:src="@drawable/xfer" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/yourTrainTrainLengthText"
|
android:id="@+id/yourTrainTrainLengthText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/yourTrainDestinationText"
|
tools:text="9 cars, platform 2"
|
||||||
android:layout_toRightOf="@id/yourTrainDestinationColorBar"
|
/>
|
||||||
android:paddingLeft="5dp" />
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Holds the bike icon and xfer icon -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/yourTrainBikeIcon"
|
||||||
|
style="@style/TrainInfoIcon"
|
||||||
|
tools:src="@drawable/bike"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/yourTrainXferIcon"
|
||||||
|
style="@style/TrainInfoIcon"
|
||||||
|
android:src="@drawable/xfer"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<com.dougkeen.bart.controls.CountdownTextView
|
<com.dougkeen.bart.controls.CountdownTextView
|
||||||
android:id="@+id/yourTrainDepartureCountdown"
|
android:id="@+id/yourTrainDepartureCountdown"
|
||||||
style="@style/DepartureCountdownText"
|
style="@style/DepartureCountdownText"
|
||||||
android:layout_alignLeft="@id/yourTrainSection"
|
bart:tickInterval="1"
|
||||||
android:layout_alignRight="@id/yourTrainSection"
|
tools:text="Leaves in 15 min, 20s (+8s)"
|
||||||
android:layout_below="@id/yourTrainTrainLengthText"
|
/>
|
||||||
bart:tickInterval="1" />
|
|
||||||
|
|
||||||
<com.dougkeen.bart.controls.CountdownTextView
|
<com.dougkeen.bart.controls.CountdownTextView
|
||||||
android:id="@+id/yourTrainArrivalCountdown"
|
android:id="@+id/yourTrainArrivalCountdown"
|
||||||
style="@style/DepartureCountdownText"
|
style="@style/DepartureCountdownText"
|
||||||
android:layout_alignLeft="@id/yourTrainSection"
|
|
||||||
android:layout_alignRight="@id/yourTrainSection"
|
|
||||||
android:layout_below="@id/yourTrainDepartureCountdown"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
bart:tickInterval="5" />
|
bart:tickInterval="5"
|
||||||
|
tools:text="Arrives ~11:12 AM (20 mins)"
|
||||||
|
/>
|
||||||
|
|
||||||
</merge>
|
</LinearLayout>
|
||||||
|
@ -92,18 +92,10 @@
|
|||||||
<item name="android:gravity">center</item>
|
<item name="android:gravity">center</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="BikeIcon">
|
<style name="TrainInfoIcon">
|
||||||
<item name="android:layout_width">wrap_content</item>
|
<item name="android:layout_width">wrap_content</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
<item name="android:layout_marginTop">5dp</item>
|
<item name="android:layout_margin">5dp</item>
|
||||||
<item name="android:layout_marginLeft">5dp</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="XferIcon">
|
|
||||||
<item name="android:layout_width">wrap_content</item>
|
|
||||||
<item name="android:layout_height">wrap_content</item>
|
|
||||||
<item name="android:layout_marginRight">87dp</item>
|
|
||||||
<item name="android:layout_marginBottom">5dp</item>
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user