forked from upstream-mirrors/OpenTracks
Intervals: added elevation gain and only shows speed or pace, depending on settings.
This commit is contained in:
@@ -16,6 +16,7 @@ public class TestDataUtil {
|
|||||||
public static final double INITIAL_LATITUDE = 37.0;
|
public static final double INITIAL_LATITUDE = 37.0;
|
||||||
public static final double INITIAL_LONGITUDE = -57.0;
|
public static final double INITIAL_LONGITUDE = -57.0;
|
||||||
public static final double ALTITUDE_INTERVAL = 2.5;
|
public static final double ALTITUDE_INTERVAL = 2.5;
|
||||||
|
public static final float ELEVATION_GAIN = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a track without any trackPoints.
|
* Create a track without any trackPoints.
|
||||||
@@ -70,7 +71,7 @@ public class TestDataUtil {
|
|||||||
trackPoint.setHeartRate_bpm(100f + i);
|
trackPoint.setHeartRate_bpm(100f + i);
|
||||||
trackPoint.setCyclingCadence_rpm(300f + i);
|
trackPoint.setCyclingCadence_rpm(300f + i);
|
||||||
trackPoint.setPower(400f + i);
|
trackPoint.setPower(400f + i);
|
||||||
trackPoint.setElevationGain(500f + i);
|
trackPoint.setElevationGain(ELEVATION_GAIN);
|
||||||
return trackPoint;
|
return trackPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -80,7 +80,7 @@ public class IntervalStatisticsTest {
|
|||||||
// given
|
// given
|
||||||
List<TrackPoint> trackPoints = buildTrackPoints(200);
|
List<TrackPoint> trackPoints = buildTrackPoints(200);
|
||||||
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
|
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
|
||||||
float distanceInterval = 3000;
|
float distanceInterval = 3000f;
|
||||||
IntervalStatistics intervalStatistics = new IntervalStatistics();
|
IntervalStatistics intervalStatistics = new IntervalStatistics();
|
||||||
|
|
||||||
// when and then
|
// when and then
|
||||||
@@ -97,7 +97,7 @@ public class IntervalStatisticsTest {
|
|||||||
// given
|
// given
|
||||||
List<TrackPoint> trackPoints = buildTrackPoints(1000);
|
List<TrackPoint> trackPoints = buildTrackPoints(1000);
|
||||||
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
|
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
|
||||||
float distanceInterval = 3000;
|
float distanceInterval = 3000f;
|
||||||
IntervalStatistics intervalStatistics = new IntervalStatistics();
|
IntervalStatistics intervalStatistics = new IntervalStatistics();
|
||||||
|
|
||||||
// when and then
|
// when and then
|
||||||
@@ -114,7 +114,7 @@ public class IntervalStatisticsTest {
|
|||||||
// given
|
// given
|
||||||
List<TrackPoint> trackPoints = buildTrackPoints(10000);
|
List<TrackPoint> trackPoints = buildTrackPoints(10000);
|
||||||
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
|
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
|
||||||
float distanceInterval = 1000;
|
float distanceInterval = 1000f;
|
||||||
IntervalStatistics intervalStatistics = new IntervalStatistics();
|
IntervalStatistics intervalStatistics = new IntervalStatistics();
|
||||||
|
|
||||||
// when and then
|
// when and then
|
||||||
@@ -126,15 +126,18 @@ public class IntervalStatisticsTest {
|
|||||||
List<IntervalStatistics.Interval> intervalList = intervalStatistics.getIntervalList();
|
List<IntervalStatistics.Interval> intervalList = intervalStatistics.getIntervalList();
|
||||||
double totalDistance = 0d;
|
double totalDistance = 0d;
|
||||||
long totalTime = 0L;
|
long totalTime = 0L;
|
||||||
|
float totalGain = 0f;
|
||||||
for (IntervalStatistics.Interval i : intervalList) {
|
for (IntervalStatistics.Interval i : intervalList) {
|
||||||
totalDistance += i.getDistance_m();
|
totalDistance += i.getDistance_m();
|
||||||
totalTime += ((i.getDistance_m() / i.getSpeed_ms()) * UnitConversions.S_TO_MS);
|
totalTime += ((i.getDistance_m() / i.getSpeed_ms()) * UnitConversions.S_TO_MS);
|
||||||
|
totalGain += i.getGain_m();
|
||||||
}
|
}
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(trackStatistics.getTotalDistance(), totalDistance, 0.01);
|
assertEquals(trackStatistics.getTotalDistance(), totalDistance, 0.01);
|
||||||
assertEquals(trackStatistics.getTotalTime() * UnitConversions.MS_TO_S, totalTime * UnitConversions.MS_TO_S, 0.1);
|
assertEquals(trackStatistics.getTotalTime() * UnitConversions.MS_TO_S, totalTime * UnitConversions.MS_TO_S, 0.1);
|
||||||
assertEquals(intervalList.size(), (int) Math.ceil(trackStatistics.getTotalDistance() / distanceInterval));
|
assertEquals(intervalList.size(), (int) Math.ceil(trackStatistics.getTotalDistance() / distanceInterval));
|
||||||
|
assertEquals(totalGain, trackPoints.size() * TestDataUtil.ELEVATION_GAIN, 0.1);
|
||||||
for (int i = 0; i < intervalList.size() - 1; i++) {
|
for (int i = 0; i < intervalList.size() - 1; i++) {
|
||||||
assertEquals(intervalList.get(i).getDistance_m(), distanceInterval, 0.001);
|
assertEquals(intervalList.get(i).getDistance_m(), distanceInterval, 0.001);
|
||||||
totalDistance -= intervalList.get(i).getDistance_m();
|
totalDistance -= intervalList.get(i).getDistance_m();
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
// Preferences
|
// Preferences
|
||||||
private boolean recordingTrackPaused;
|
private boolean recordingTrackPaused;
|
||||||
|
|
||||||
// Intervals recording fragment needs Track.Id when the activity creates it.
|
// Intervals recording fragment needs Track.Id when the activity creates it and knowing when category change.
|
||||||
private OnTrackIdListener intervalsListener;
|
private OnTrackRecordingListener intervalsListener;
|
||||||
|
|
||||||
private final Runnable bindChangedCallback = new Runnable() {
|
private final Runnable bindChangedCallback = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -370,6 +370,7 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
Track track = contentProviderUtils.getTrack(trackId);
|
Track track = contentProviderUtils.getTrack(trackId);
|
||||||
String category = getString(TrackIconUtils.getIconActivityType(iconValue));
|
String category = getString(TrackIconUtils.getIconActivityType(iconValue));
|
||||||
TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils);
|
TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils);
|
||||||
|
intervalsListener.onCategoryChanged(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
|
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||||
@@ -417,11 +418,12 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnTrackIdListener {
|
public interface OnTrackRecordingListener {
|
||||||
void onTrackId(Track.Id trackId);
|
void onTrackId(Track.Id trackId);
|
||||||
|
void onCategoryChanged(String category);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTrackIdListener(OnTrackIdListener listener) {
|
public void setTrackIdListener(OnTrackRecordingListener listener) {
|
||||||
this.intervalsListener = listener;
|
this.intervalsListener = listener;
|
||||||
if (trackId != null) {
|
if (trackId != null) {
|
||||||
listener.onTrackId(trackId);
|
listener.onTrackId(trackId);
|
||||||
|
|||||||
@@ -23,10 +23,12 @@ public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.I
|
|||||||
private StackMode stackMode;
|
private StackMode stackMode;
|
||||||
private boolean metricUnits;
|
private boolean metricUnits;
|
||||||
private float sumDistance_m;
|
private float sumDistance_m;
|
||||||
|
private String category;
|
||||||
|
|
||||||
public IntervalStatisticsAdapter(Context context, List<IntervalStatistics.Interval> intervalList, StackMode stackMode) {
|
public IntervalStatisticsAdapter(Context context, List<IntervalStatistics.Interval> intervalList, String category, StackMode stackMode) {
|
||||||
super(context, R.layout.interval_stats_list_item, intervalList);
|
super(context, R.layout.interval_stats_list_item, intervalList);
|
||||||
metricUnits = PreferencesUtils.isMetricUnits(context);
|
metricUnits = PreferencesUtils.isMetricUnits(context);
|
||||||
|
this.category = category;
|
||||||
this.stackMode = stackMode;
|
this.stackMode = stackMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,8 +45,8 @@ public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.I
|
|||||||
intervalView = LayoutInflater.from(getContext()).inflate(R.layout.interval_stats_list_item, parent, false);
|
intervalView = LayoutInflater.from(getContext()).inflate(R.layout.interval_stats_list_item, parent, false);
|
||||||
|
|
||||||
viewHolder.distance = intervalView.findViewById(R.id.interval_item_distance);
|
viewHolder.distance = intervalView.findViewById(R.id.interval_item_distance);
|
||||||
viewHolder.speed = intervalView.findViewById(R.id.interval_item_speed);
|
viewHolder.rate = intervalView.findViewById(R.id.interval_item_rate);
|
||||||
viewHolder.pace = intervalView.findViewById(R.id.interval_item_pace);
|
viewHolder.gain = intervalView.findViewById(R.id.interval_item_gain);
|
||||||
|
|
||||||
intervalView.setTag(viewHolder);
|
intervalView.setTag(viewHolder);
|
||||||
} else {
|
} else {
|
||||||
@@ -58,11 +60,16 @@ public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.I
|
|||||||
}
|
}
|
||||||
viewHolder.distance.setText(StringUtils.formatDistance(getContext(), sumDistance_m, metricUnits));
|
viewHolder.distance.setText(StringUtils.formatDistance(getContext(), sumDistance_m, metricUnits));
|
||||||
|
|
||||||
Pair<String, String> speedParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, true);
|
if (PreferencesUtils.isReportSpeed(getContext(), category)) {
|
||||||
viewHolder.speed.setText(speedParts.first + " " + speedParts.second);
|
Pair<String, String> speedParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, true);
|
||||||
|
viewHolder.rate.setText(speedParts.first + " " + speedParts.second);
|
||||||
|
} else {
|
||||||
|
Pair<String, String> paceParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, false);
|
||||||
|
viewHolder.rate.setText(paceParts.first + " " + paceParts.second);
|
||||||
|
}
|
||||||
|
|
||||||
Pair<String, String> paceParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, false);
|
Pair<String, String> gainParts = StringUtils.formatElevation(getContext(), interval.getGain_m(), metricUnits);
|
||||||
viewHolder.pace.setText(paceParts.first + " " + paceParts.second);
|
viewHolder.gain.setText(gainParts.first + " " + gainParts.second);
|
||||||
|
|
||||||
return intervalView;
|
return intervalView;
|
||||||
}
|
}
|
||||||
@@ -77,7 +84,7 @@ public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.I
|
|||||||
|
|
||||||
private static class ViewHolder {
|
private static class ViewHolder {
|
||||||
private TextView distance;
|
private TextView distance;
|
||||||
private TextView speed;
|
private TextView rate;
|
||||||
private TextView pace;
|
private TextView gain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import de.dennisguse.opentracks.R;
|
|||||||
import de.dennisguse.opentracks.TrackRecordingActivity;
|
import de.dennisguse.opentracks.TrackRecordingActivity;
|
||||||
import de.dennisguse.opentracks.adapters.IntervalStatisticsAdapter;
|
import de.dennisguse.opentracks.adapters.IntervalStatisticsAdapter;
|
||||||
import de.dennisguse.opentracks.content.data.Track;
|
import de.dennisguse.opentracks.content.data.Track;
|
||||||
|
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.UnitConversions;
|
import de.dennisguse.opentracks.util.UnitConversions;
|
||||||
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
||||||
@@ -46,7 +47,10 @@ public class IntervalsFragment extends Fragment {
|
|||||||
protected Spinner spinnerIntervals;
|
protected Spinner spinnerIntervals;
|
||||||
private ArrayAdapter<IntervalStatisticsModel.IntervalOption> spinnerAdapter;
|
private ArrayAdapter<IntervalStatisticsModel.IntervalOption> spinnerAdapter;
|
||||||
|
|
||||||
|
private TextView rateLabel;
|
||||||
|
|
||||||
private Track.Id trackId;
|
private Track.Id trackId;
|
||||||
|
private String category;
|
||||||
|
|
||||||
protected final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
|
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 (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) {
|
||||||
@@ -54,6 +58,7 @@ public class IntervalsFragment extends Fragment {
|
|||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
spinnerAdapter.notifyDataSetChanged();
|
spinnerAdapter.notifyDataSetChanged();
|
||||||
|
setRateLabel();
|
||||||
intervalChanged();
|
intervalChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,11 +86,13 @@ public class IntervalsFragment extends Fragment {
|
|||||||
intervalUnit = PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile);
|
intervalUnit = PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile);
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
trackId = savedInstanceState.getParcelable(TRACK_ID_KEY);
|
setTrackId(savedInstanceState.getParcelable(TRACK_ID_KEY));
|
||||||
} else {
|
} else {
|
||||||
trackId = getArguments().getParcelable(TRACK_ID_KEY);
|
setTrackId(getArguments().getParcelable(TRACK_ID_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rateLabel = view.findViewById(R.id.interval_rate);
|
||||||
|
|
||||||
intervalListView = view.findViewById(R.id.interval_list);
|
intervalListView = view.findViewById(R.id.interval_list);
|
||||||
intervalListView.setEmptyView(view.findViewById(R.id.interval_list_empty_view));
|
intervalListView.setEmptyView(view.findViewById(R.id.interval_list_empty_view));
|
||||||
|
|
||||||
@@ -126,6 +133,7 @@ public class IntervalsFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setRateLabel();
|
||||||
intervalChanged();
|
intervalChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +155,12 @@ public class IntervalsFragment extends Fragment {
|
|||||||
outState.putParcelable(TRACK_ID_KEY, trackId);
|
outState.putParcelable(TRACK_ID_KEY, trackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setTrackId(trackId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update intervals through {@link IntervalStatisticsModel} view model.
|
* Update intervals through {@link IntervalStatisticsModel} view model.
|
||||||
*/
|
*/
|
||||||
@@ -158,7 +172,7 @@ public class IntervalsFragment extends Fragment {
|
|||||||
LiveData<IntervalStatistics> liveData = viewModel.getIntervalStats(trackId, selectedInterval);
|
LiveData<IntervalStatistics> liveData = viewModel.getIntervalStats(trackId, selectedInterval);
|
||||||
liveData.observe(getActivity(), intervalStatistics -> {
|
liveData.observe(getActivity(), intervalStatistics -> {
|
||||||
if (intervalStatistics != null) {
|
if (intervalStatistics != null) {
|
||||||
adapter = new IntervalStatisticsAdapter(getContext(), intervalStatistics.getIntervalList(), stackModeListView);
|
adapter = new IntervalStatisticsAdapter(getContext(), intervalStatistics.getIntervalList(), category, stackModeListView);
|
||||||
intervalListView.setAdapter(adapter);
|
intervalListView.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -166,9 +180,29 @@ public class IntervalsFragment extends Fragment {
|
|||||||
|
|
||||||
public void setTrackId(Track.Id trackId) {
|
public void setTrackId(Track.Id trackId) {
|
||||||
this.trackId = trackId;
|
this.trackId = trackId;
|
||||||
|
if (this.trackId != null) {
|
||||||
|
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getContext());
|
||||||
|
Track track = contentProviderUtils.getTrack(this.trackId);
|
||||||
|
setCategory(track.getCategory());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IntervalsRecordingFragment extends IntervalsFragment implements TrackRecordingActivity.OnTrackIdListener {
|
public void setCategory(String category) {
|
||||||
|
if (this.category == null || !this.category.equals(category)) {
|
||||||
|
this.category = category;
|
||||||
|
setRateLabel();
|
||||||
|
intervalChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRateLabel() {
|
||||||
|
if (rateLabel != null) {
|
||||||
|
boolean reportSpeed = PreferencesUtils.isReportSpeed(getContext(), category);
|
||||||
|
rateLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class IntervalsRecordingFragment extends IntervalsFragment implements TrackRecordingActivity.OnTrackRecordingListener {
|
||||||
// Refreshing intervals stats it's not so demanding so 5 seconds is enough to balance performance and user experience.
|
// 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 static final long UI_UPDATE_INTERVAL = 5 * UnitConversions.ONE_SECOND_MS;
|
||||||
|
|
||||||
@@ -221,5 +255,10 @@ public class IntervalsFragment extends Fragment {
|
|||||||
public void onTrackId(Track.Id trackId) {
|
public void onTrackId(Track.Id trackId) {
|
||||||
setTrackId(trackId);
|
setTrackId(trackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCategoryChanged(String category) {
|
||||||
|
setCategory(category);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,7 @@ public class IntervalStatistics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Interval interval = new Interval();
|
Interval interval = new Interval();
|
||||||
|
interval.gain_m += trackPointList.get(0).hasElevationGain() ? trackPointList.get(0).getElevationGain() : 0;
|
||||||
for (int i = 1; i < trackPointList.size(); i++) {
|
for (int i = 1; i < trackPointList.size(); i++) {
|
||||||
TrackPoint prevTrackPoint = trackPointList.get(i - 1);
|
TrackPoint prevTrackPoint = trackPointList.get(i - 1);
|
||||||
TrackPoint trackPoint = trackPointList.get(i);
|
TrackPoint trackPoint = trackPointList.get(i);
|
||||||
@@ -31,6 +32,7 @@ public class IntervalStatistics {
|
|||||||
if (LocationUtils.isValidLocation(trackPoint.getLocation()) && LocationUtils.isValidLocation(prevTrackPoint.getLocation())) {
|
if (LocationUtils.isValidLocation(trackPoint.getLocation()) && LocationUtils.isValidLocation(prevTrackPoint.getLocation())) {
|
||||||
interval.distance_m += prevTrackPoint.distanceTo(trackPoint);
|
interval.distance_m += prevTrackPoint.distanceTo(trackPoint);
|
||||||
interval.time_ms += trackPoint.getTime() - prevTrackPoint.getTime();
|
interval.time_ms += trackPoint.getTime() - prevTrackPoint.getTime();
|
||||||
|
interval.gain_m += trackPoint.hasElevationGain() ? trackPoint.getElevationGain() : 0;
|
||||||
|
|
||||||
if (interval.distance_m >= distanceInterval_m) {
|
if (interval.distance_m >= distanceInterval_m) {
|
||||||
float adjustFactor = distanceInterval_m / interval.distance_m;
|
float adjustFactor = distanceInterval_m / interval.distance_m;
|
||||||
@@ -80,17 +82,20 @@ public class IntervalStatistics {
|
|||||||
public static class Interval {
|
public static class Interval {
|
||||||
private float distance_m = 0f;
|
private float distance_m = 0f;
|
||||||
private float time_ms = 0f;
|
private float time_ms = 0f;
|
||||||
|
private float gain_m = 0f;
|
||||||
|
|
||||||
public Interval() {}
|
public Interval() {}
|
||||||
|
|
||||||
public Interval(float distance_m, float time_ms) {
|
public Interval(float distance_m, float time_ms) {
|
||||||
this.distance_m = distance_m;
|
this.distance_m = distance_m;
|
||||||
this.time_ms = time_ms;
|
this.time_ms = time_ms;
|
||||||
|
this.gain_m = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Interval(Interval i) {
|
public Interval(Interval i) {
|
||||||
distance_m = i.distance_m;
|
distance_m = i.distance_m;
|
||||||
time_ms = i.time_ms;
|
time_ms = i.time_ms;
|
||||||
|
gain_m = i.gain_m;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDistance_m() {
|
public float getDistance_m() {
|
||||||
@@ -111,5 +116,9 @@ public class IntervalStatistics {
|
|||||||
}
|
}
|
||||||
return distance_m / (float) (time_ms * UnitConversions.MS_TO_S);
|
return distance_m / (float) (time_ms * UnitConversions.MS_TO_S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getGain_m() {
|
||||||
|
return gain_m;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M7,14l5,-5 5,5z"/>
|
||||||
|
</vector>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@@ -42,7 +43,7 @@
|
|||||||
android:text="@string/stats_distance" />
|
android:text="@string/stats_distance" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_speed"
|
android:id="@+id/interval_rate"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
@@ -50,10 +51,10 @@
|
|||||||
android:layout_margin="1dp"
|
android:layout_margin="1dp"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:text="@string/stats_speed" />
|
tools:text="Speed"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_pace"
|
android:id="@+id/interval_elevation"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
@@ -61,7 +62,7 @@
|
|||||||
android:layout_margin="1dp"
|
android:layout_margin="1dp"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:text="@string/stats_pace" />
|
android:text="@string/stats_elevation" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -5,28 +5,43 @@
|
|||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_item_distance"
|
android:id="@+id/interval_item_distance"
|
||||||
style="@style/TextMedium"
|
android:layout_width="0dp"
|
||||||
android:layout_width="0dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_weight="1"
|
||||||
android:layout_weight="1"
|
android:layout_gravity="center_vertical"
|
||||||
tools:text="1 km" />
|
style="@style/TextMedium"
|
||||||
|
tools:text="1 km" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_item_speed"
|
android:id="@+id/interval_item_rate"
|
||||||
style="@style/TextMedium"
|
android:layout_width="0dp"
|
||||||
android:layout_width="0dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_weight="1"
|
||||||
android:layout_weight="1"
|
android:layout_gravity="center_vertical"
|
||||||
tools:text="15 km/h" />
|
style="@style/TextMedium"
|
||||||
|
tools:text="15 km/h" />
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/interval_item_pace"
|
android:layout_width="0dp"
|
||||||
style="@style/TextMedium"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="0dp"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="horizontal">
|
||||||
android:layout_weight="1"
|
|
||||||
tools:text="4:00" />
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_arrow_drop_up_24" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/interval_item_gain"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
style="@style/TextMedium"
|
||||||
|
tools:text="100 m" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user