forked from upstream-mirrors/OpenTracks
Interval Stats: improve code and fixed some UI issues.
This commit is contained in:
+8
-10
@@ -23,9 +23,7 @@ public class IntervalStatisticsTest {
|
||||
|
||||
private List<TrackPoint> buildTrackPoints(int numberOfTrackPoints) {
|
||||
Pair<Track, TrackPoint[]> pair = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), numberOfTrackPoints);
|
||||
List<TrackPoint> trackPoints = Arrays.asList(pair.second);
|
||||
|
||||
return trackPoints;
|
||||
return Arrays.asList(pair.second);
|
||||
}
|
||||
|
||||
private TrackStatistics buildTrackStatistics(List<TrackPoint> trackPoints) {
|
||||
@@ -40,10 +38,10 @@ public class IntervalStatisticsTest {
|
||||
* Tests that build method compute the distance correctly comparing the result with TrackStatisticsUpdater result.
|
||||
*/
|
||||
@Test
|
||||
public void testBuild_1() {
|
||||
public void testBuild_1() {
|
||||
// With 50 points and interval distance of 1000m.
|
||||
|
||||
// given
|
||||
// given
|
||||
List<TrackPoint> trackPoints = buildTrackPoints(50);
|
||||
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
|
||||
float distanceInterval = 1000f;
|
||||
@@ -127,8 +125,8 @@ public class IntervalStatisticsTest {
|
||||
double totalDistance = 0d;
|
||||
long totalTime = 0L;
|
||||
for (IntervalStatistics.Interval i : intervalList) {
|
||||
totalDistance += i.getDistance();
|
||||
totalTime += ((i.getDistance() / i.getSpeed()) * UnitConversions.S_TO_MS);
|
||||
totalDistance += i.getDistance_m();
|
||||
totalTime += ((i.getDistance_m() / i.getSpeed_ms()) * UnitConversions.S_TO_MS);
|
||||
}
|
||||
|
||||
// then
|
||||
@@ -136,9 +134,9 @@ public class IntervalStatisticsTest {
|
||||
Assert.assertEquals(trackStatistics.getTotalTime() * UnitConversions.MS_TO_S, totalTime * UnitConversions.MS_TO_S, 0.1);
|
||||
Assert.assertEquals(intervalList.size(), (int) Math.ceil(trackStatistics.getTotalDistance() / distanceInterval));
|
||||
for (int i = 0; i < intervalList.size() - 1; i++) {
|
||||
Assert.assertEquals(intervalList.get(i).getDistance(), distanceInterval, 0.001);
|
||||
totalDistance -= intervalList.get(i).getDistance();
|
||||
Assert.assertEquals(intervalList.get(i).getDistance_m(), distanceInterval, 0.001);
|
||||
totalDistance -= intervalList.get(i).getDistance_m();
|
||||
}
|
||||
Assert.assertEquals(intervalList.get(intervalList.size() - 1).getDistance(), totalDistance, 0.01);
|
||||
Assert.assertEquals(intervalList.get(intervalList.size() - 1).getDistance_m(), totalDistance, 0.01);
|
||||
}
|
||||
}
|
||||
@@ -381,9 +381,9 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
||||
public Fragment getItem(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return new StatisticsRecordingFragment();
|
||||
return StatisticsRecordingFragment.newInstance();
|
||||
case 1:
|
||||
return new IntervalsRecordingFragment();
|
||||
return IntervalsRecordingFragment.newInstance();
|
||||
case 2:
|
||||
return ChartFragment.newInstance(false);
|
||||
case 3:
|
||||
|
||||
@@ -21,7 +21,7 @@ import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
||||
public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.Interval> {
|
||||
|
||||
private boolean metricUnits;
|
||||
private float accDistance = 0f;
|
||||
private float sumDistance_m = 0f;
|
||||
|
||||
public IntervalStatisticsAdapter(Context context, List<IntervalStatistics.Interval> intervalList) {
|
||||
super(context, R.layout.interval_stats_list_item, intervalList);
|
||||
@@ -48,11 +48,14 @@ public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.I
|
||||
viewHolder = (ViewHolder) intervalView.getTag();
|
||||
}
|
||||
|
||||
accDistance += interval.getDistance();
|
||||
viewHolder.distance.setText(StringUtils.formatDistance(getContext(), accDistance, metricUnits));
|
||||
Pair<String, String> speedParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed(), metricUnits, true);
|
||||
sumDistance_m += interval.getDistance_m();
|
||||
viewHolder.distance.setText(StringUtils.formatDistance(getContext(), sumDistance_m, metricUnits));
|
||||
|
||||
Pair<String, String> speedParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, true);
|
||||
viewHolder.speed.setText(speedParts.first + " " + speedParts.second);
|
||||
viewHolder.pace.setText(StringUtils.getSpeedParts(getContext(), interval.getSpeed(), metricUnits, false).first);
|
||||
|
||||
Pair<String, String> paceParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, false);
|
||||
viewHolder.pace.setText(paceParts.first + " " + paceParts.second);
|
||||
|
||||
return intervalView;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import de.dennisguse.opentracks.util.UnitConversions;
|
||||
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
||||
import de.dennisguse.opentracks.viewmodels.IntervalStatisticsModel;
|
||||
import de.dennisguse.opentracks.views.IntervalListView;
|
||||
import de.dennisguse.opentracks.views.IntervalReverseListView;
|
||||
|
||||
/**
|
||||
* A fragment to display the intervals from recording track.
|
||||
@@ -29,29 +28,27 @@ public class IntervalsRecordingFragment extends Fragment implements IntervalList
|
||||
|
||||
private static final String TAG = IntervalsRecordingFragment.class.getSimpleName();
|
||||
|
||||
// Refreshing intervals stats it's not so demanding so 5 seconds is enough to balance performance and user experience.
|
||||
private static final long UI_UPDATE_INTERVAL = 5 * UnitConversions.ONE_SECOND_MS;
|
||||
|
||||
private IntervalStatisticsModel viewModel;
|
||||
private IntervalReverseListView intervalListView;
|
||||
private IntervalListView.IntervalReverseListView intervalListView;
|
||||
|
||||
private class IntervalRunner implements Runnable {
|
||||
private boolean stopped = false;
|
||||
public static Fragment newInstance() {
|
||||
return new IntervalsRecordingFragment();
|
||||
}
|
||||
|
||||
private final Runnable intervalRunner = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!stopped) {
|
||||
if (isResumed()) {
|
||||
updateIntervals();
|
||||
intervalHandler.postDelayed(intervalRunner, UI_UPDATE_INTERVAL);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void stop() {
|
||||
stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
private Handler intervalHandler = null;
|
||||
private IntervalRunner intervalRunner = null;
|
||||
private Handler intervalHandler;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
@@ -64,8 +61,9 @@ public class IntervalsRecordingFragment extends Fragment implements IntervalList
|
||||
|
||||
intervalHandler = new Handler();
|
||||
|
||||
intervalListView = new IntervalReverseListView(getActivity(), this);
|
||||
intervalListView = new IntervalListView.IntervalReverseListView(getActivity(), this);
|
||||
intervalListView.setId(View.generateViewId());
|
||||
intervalListView.findViewById(R.id.interval_title_label).setVisibility(View.GONE);
|
||||
LinearLayout linearLayout = view.findViewById(R.id.root_view);
|
||||
linearLayout.removeAllViews();
|
||||
linearLayout.addView(intervalListView);
|
||||
@@ -76,19 +74,13 @@ public class IntervalsRecordingFragment extends Fragment implements IntervalList
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (intervalRunner == null) {
|
||||
intervalRunner = new IntervalRunner();
|
||||
intervalRunner.run();
|
||||
}
|
||||
intervalHandler.post(intervalRunner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (intervalRunner != null) {
|
||||
intervalRunner.stop();
|
||||
intervalRunner = null;
|
||||
}
|
||||
intervalHandler.removeCallbacks(intervalRunner);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,7 +98,7 @@ public class IntervalsRecordingFragment extends Fragment implements IntervalList
|
||||
* @param interval intervals will split in this interval if not null. If it's null then view model will use the default one.
|
||||
*/
|
||||
private void updateIntervals(@Nullable IntervalStatisticsModel.IntervalOption interval) {
|
||||
if (viewModel == null | intervalListView == null) {
|
||||
if (viewModel == null || intervalListView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,12 +54,12 @@ public class StatisticsRecordedFragment extends Fragment implements IntervalList
|
||||
|
||||
private static final String TRACK_ID_KEY = "trackId";
|
||||
|
||||
private TrackStatistics trackStatistics = null;
|
||||
private TrackStatistics trackStatistics;
|
||||
private String category = "";
|
||||
private Track track;
|
||||
|
||||
private IntervalStatisticsModel viewModel = null;
|
||||
private IntervalListView intervalListView = null;
|
||||
private IntervalStatisticsModel viewModel;
|
||||
private IntervalListView intervalListView;
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
|
||||
if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) {
|
||||
@@ -299,7 +299,6 @@ public class StatisticsRecordedFragment extends Fragment implements IntervalList
|
||||
speedMovingUnit.setText(parts.second);
|
||||
}
|
||||
|
||||
// Set intervals.
|
||||
addIntervals();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,13 +55,17 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
|
||||
|
||||
private TrackRecordingServiceConnection trackRecordingServiceConnection = new TrackRecordingServiceConnection();
|
||||
|
||||
private TrackPoint lastTrackPoint = null;
|
||||
private TrackStatistics lastTrackStatistics = null;
|
||||
private TrackPoint lastTrackPoint;
|
||||
private TrackStatistics lastTrackStatistics;
|
||||
|
||||
private String category = "";
|
||||
@Deprecated //TODO This should be handled somewhere else; not in the UI.
|
||||
private int recordingGpsAccuracy;
|
||||
|
||||
public static Fragment newInstance() {
|
||||
return new StatisticsRecordingFragment();
|
||||
}
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
|
||||
@@ -51,8 +51,6 @@ public class UnitConversions {
|
||||
public static final double MM_TO_M = 0.001;
|
||||
|
||||
// Distance
|
||||
// multiplication factor to convert miles to meters
|
||||
public static final double MI_TO_M = 1609.344;
|
||||
// multiplication factor to convert miles to feet
|
||||
public static final double MI_TO_FT = 5280.0;
|
||||
// multiplication factor to convert feet to miles
|
||||
@@ -67,6 +65,10 @@ public class UnitConversions {
|
||||
public static final double M_TO_FT = M_TO_MI * MI_TO_FT;
|
||||
// multiplication factor to convert meters per second to kilometers per hour
|
||||
public static final double MPS_TO_KMH = M_TO_KM / (S_TO_MIN * MIN_TO_HR);
|
||||
// multiplication factor to convert miles to km
|
||||
public static final double MI_TO_KM = 1 / KM_TO_MI;
|
||||
// multiplication factor to convert miles to m
|
||||
public static final double MI_TO_M = MI_TO_KM * KM_TO_M;
|
||||
|
||||
private UnitConversions() {
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ import de.dennisguse.opentracks.util.LocationUtils;
|
||||
import de.dennisguse.opentracks.util.UnitConversions;
|
||||
|
||||
public class IntervalStatistics {
|
||||
List<Interval> intervalList;
|
||||
List<Interval> intervalList = new ArrayList<>();
|
||||
|
||||
public void build(List<TrackPoint> trackPointList, float distanceInterval) {
|
||||
intervalList = new ArrayList<>();
|
||||
intervalList.clear();
|
||||
|
||||
if (trackPointList == null || trackPointList.size() == 0) {
|
||||
return;
|
||||
@@ -23,27 +23,22 @@ public class IntervalStatistics {
|
||||
TrackPoint trackPoint = trackPointList.get(i);
|
||||
|
||||
if (LocationUtils.isValidLocation(trackPoint.getLocation()) && LocationUtils.isValidLocation(prevTrackPoint.getLocation())) {
|
||||
interval.distance += prevTrackPoint.distanceTo(trackPoint);
|
||||
interval.time += trackPoint.getTime() - prevTrackPoint.getTime();
|
||||
interval.distance_m += prevTrackPoint.distanceTo(trackPoint);
|
||||
interval.time_ms += trackPoint.getTime() - prevTrackPoint.getTime();
|
||||
|
||||
if (interval.distance >= distanceInterval) {
|
||||
float adjustFactor = distanceInterval / interval.distance;
|
||||
if (interval.distance_m >= distanceInterval) {
|
||||
float adjustFactor = distanceInterval / interval.distance_m;
|
||||
Interval adjustedInterval = new Interval(interval);
|
||||
adjustedInterval.distance *= adjustFactor;
|
||||
adjustedInterval.time *= adjustFactor;
|
||||
adjustedInterval.adjust(adjustFactor);
|
||||
|
||||
intervalList.add(adjustedInterval);
|
||||
|
||||
Interval newInterval = new Interval();
|
||||
newInterval.distance = interval.distance - adjustedInterval.distance;
|
||||
newInterval.time = interval.time - adjustedInterval.time;
|
||||
|
||||
interval = newInterval;
|
||||
interval = new Interval(interval.distance_m - adjustedInterval.distance_m, interval.time_ms - adjustedInterval.time_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (interval.distance > 1f) {
|
||||
if (interval.distance_m > 1f) {
|
||||
intervalList.add(interval);
|
||||
}
|
||||
}
|
||||
@@ -53,28 +48,38 @@ public class IntervalStatistics {
|
||||
}
|
||||
|
||||
public static class Interval {
|
||||
private float distance = 0f;
|
||||
private float time = 0f;
|
||||
|
||||
public float getDistance() {
|
||||
return distance;
|
||||
}
|
||||
private float distance_m = 0f;
|
||||
private float time_ms = 0f;
|
||||
|
||||
public Interval() {}
|
||||
|
||||
public Interval(float distance_m, float time_ms) {
|
||||
this.distance_m = distance_m;
|
||||
this.time_ms = time_ms;
|
||||
}
|
||||
|
||||
public Interval(Interval i) {
|
||||
distance = i.distance;
|
||||
time = i.time;
|
||||
distance_m = i.distance_m;
|
||||
time_ms = i.time_ms;
|
||||
}
|
||||
|
||||
public float getDistance_m() {
|
||||
return distance_m;
|
||||
}
|
||||
|
||||
public void adjust(float adjustFactor) {
|
||||
distance_m *= adjustFactor;
|
||||
time_ms *= adjustFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return speed of the interval in m/s.
|
||||
*/
|
||||
public float getSpeed() {
|
||||
if (distance == 0f) {
|
||||
public float getSpeed_ms() {
|
||||
if (distance_m == 0f) {
|
||||
return 0f;
|
||||
}
|
||||
return distance / (float) (time * UnitConversions.MS_TO_S);
|
||||
return distance_m / (float) (time_ms * UnitConversions.MS_TO_S);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,34 +83,8 @@ public class IntervalStatisticsModel extends AndroidViewModel {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos position of the interval option.
|
||||
* @return the interval option that is in the position pos.
|
||||
*/
|
||||
public static IntervalOption getIntervalOption(int pos) {
|
||||
if (values().length > pos) {
|
||||
return values()[pos];
|
||||
} else {
|
||||
return OPTION_1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a string array with all options.
|
||||
*/
|
||||
public static String[] getAllValues() {
|
||||
IntervalOption[] options = values();
|
||||
String[] values = new String[options.length];
|
||||
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
values[i] = String.valueOf(options[i].getValue());
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
@@ -28,37 +29,35 @@ public class IntervalListView extends LinearLayout {
|
||||
protected Spinner spinnerIntervals;
|
||||
protected TextView spinnerIntervalsUnit;
|
||||
|
||||
protected Context context;
|
||||
protected IntervalListListener listener;
|
||||
|
||||
protected final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
|
||||
if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) {
|
||||
if (spinnerIntervalsUnit != null) {
|
||||
spinnerIntervalsUnit.setText(PreferencesUtils.isMetricUnits(context) ? context.getString(R.string.unit_kilometer) : context.getString(R.string.unit_mile));
|
||||
spinnerIntervalsUnit.setText(PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public IntervalListView(Context context, IntervalListListener listener) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
this.listener = listener;
|
||||
PreferencesUtils.register(getContext(), sharedPreferenceChangeListener);
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
inflate(getContext(), R.layout.interval_list_view, this);
|
||||
linearLayoutIntervals = findViewById(R.id.interval_list);
|
||||
spinnerIntervals = findViewById(R.id.spinner_intervals);
|
||||
spinnerIntervals.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, IntervalStatisticsModel.IntervalOption.getAllValues()));
|
||||
|
||||
int[] intValues = Arrays.stream(IntervalStatisticsModel.IntervalOption.values()).mapToInt(i -> i.getValue()).toArray();
|
||||
|
||||
spinnerIntervals.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, Arrays.stream(intValues).mapToObj(String::valueOf).toArray(String[]::new)));
|
||||
spinnerIntervalsUnit = findViewById(R.id.spinner_intervals_unit);
|
||||
spinnerIntervalsUnit.setText(PreferencesUtils.isMetricUnits(context) ? context.getString(R.string.unit_kilometer) : context.getString(R.string.unit_mile));
|
||||
spinnerIntervalsUnit.setText(PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile));
|
||||
|
||||
spinnerIntervals.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
IntervalStatisticsModel.IntervalOption interval = IntervalStatisticsModel.IntervalOption.getIntervalOption(i);
|
||||
IntervalStatisticsModel.IntervalOption interval = IntervalStatisticsModel.IntervalOption.values()[i];
|
||||
listener.intervalChanged(interval);
|
||||
}
|
||||
|
||||
@@ -75,22 +74,47 @@ public class IntervalListView extends LinearLayout {
|
||||
linearLayoutIntervals = null;
|
||||
spinnerIntervals = null;
|
||||
spinnerIntervalsUnit = null;
|
||||
context = null;
|
||||
listener = null;
|
||||
}
|
||||
|
||||
public void display(List<IntervalStatistics.Interval> intervalList) {
|
||||
if (intervalList != null) {
|
||||
adapter = new IntervalStatisticsAdapter(getContext(), intervalList);
|
||||
linearLayoutIntervals.removeAllViews();
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
View intervalView = adapter.getView(i, null, linearLayoutIntervals);
|
||||
linearLayoutIntervals.addView(intervalView);
|
||||
}
|
||||
if (intervalList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
adapter = new IntervalStatisticsAdapter(getContext(), intervalList);
|
||||
linearLayoutIntervals.removeAllViews();
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
View intervalView = adapter.getView(i, null, linearLayoutIntervals);
|
||||
linearLayoutIntervals.addView(intervalView);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IntervalListListener {
|
||||
void intervalChanged(IntervalStatisticsModel.IntervalOption interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* LinearLayout view used to build a list of intervals in a reverse mode, the last one will appear in the first position on the LinearLayout.
|
||||
* This class is an specialization of {@link IntervalListView} that display the views contained in the LinearLayout in a reverse mode.
|
||||
*/
|
||||
public static class IntervalReverseListView extends IntervalListView {
|
||||
|
||||
public IntervalReverseListView(Context context, IntervalListListener listener) {
|
||||
super(context, listener);
|
||||
}
|
||||
|
||||
public void display(List<IntervalStatistics.Interval> intervalList) {
|
||||
if (intervalList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
adapter = new IntervalStatisticsAdapter(getContext(), intervalList);
|
||||
linearLayoutIntervals.removeAllViews();
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
View intervalView = adapter.getView(i, null, linearLayoutIntervals);
|
||||
linearLayoutIntervals.addView(intervalView, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package de.dennisguse.opentracks.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.adapters.IntervalStatisticsAdapter;
|
||||
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
||||
|
||||
/**
|
||||
* LinearLayout view used to build a list of intervals in a reverse mode, the last one will appear in the first position on the LinearLayout.
|
||||
* This class is an specialization of {@link IntervalListView} that display the views contained in the LinearLayout in a reverse mode.
|
||||
*/
|
||||
public class IntervalReverseListView extends IntervalListView {
|
||||
|
||||
public IntervalReverseListView(Context context, IntervalListListener listener) {
|
||||
super(context, listener);
|
||||
}
|
||||
|
||||
public void display(List<IntervalStatistics.Interval> intervalList) {
|
||||
if (intervalList != null) {
|
||||
adapter = new IntervalStatisticsAdapter(getContext(), intervalList);
|
||||
linearLayoutIntervals.removeAllViews();
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
View intervalView = adapter.getView(i, null, linearLayoutIntervals);
|
||||
linearLayoutIntervals.addView(intervalView, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/interval_title_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/StatsSmallLabel"
|
||||
@@ -27,7 +28,7 @@
|
||||
android:id="@+id/spinner_intervals"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/SpinnerCustom"/>
|
||||
android:gravity="center" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/spinner_intervals_unit"
|
||||
|
||||
Reference in New Issue
Block a user