diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java b/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java index 0b465801a..eb16d2d4d 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java @@ -64,6 +64,7 @@ public class DescriptionGeneratorTest { stats.setMaxElevation(550); stats.setMinElevation(-500); stats.setTotalElevationGain(6000); + stats.setTotalElevationLoss(6000); stats.setStartTime_ms(START_TIME); track.setTrackStatistics(stats); track.setCategory("hiking"); @@ -84,6 +85,7 @@ public class DescriptionGeneratorTest { + "Max elevation: 550 m (1804 ft)
" + "Min elevation: -500 m (-1640 ft)
" + "Elevation gain: 6000 m (19685 ft)
" + + "Elevation loss: 6000 m (19685 ft)
" + "Recorded: " + StringUtils.formatDateTime(context, START_TIME) + "
"; assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true)); @@ -100,6 +102,7 @@ public class DescriptionGeneratorTest { stats.setMaxElevation(Double.POSITIVE_INFINITY); stats.setMinElevation(Double.NEGATIVE_INFINITY); stats.setTotalElevationGain(6000); + stats.setTotalElevationLoss(6000); stats.setStartTime_ms(START_TIME); track.setTrackStatistics(stats); track.setCategory("hiking"); @@ -118,6 +121,7 @@ public class DescriptionGeneratorTest { + "Average moving pace: 0:15 min/km (0:24 min/mi)
" + "Fastest pace: 0:10 min/km (0:16 min/mi)
" + "Elevation gain: 6000 m (19685 ft)
" + + "Elevation loss: 6000 m (19685 ft)
" + "Recorded: " + StringUtils.formatDateTime(context, START_TIME) + "
"; assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true)); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/sensors/ElevationSumManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/sensors/ElevationSumManagerTest.java index e997fc7b1..fd3bc84bb 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/sensors/ElevationSumManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/sensors/ElevationSumManagerTest.java @@ -32,7 +32,7 @@ public class ElevationSumManagerTest { // then Assert.assertEquals(0f, elevationSumManager.getElevationGain_m(), 0.01); - Assert.assertEquals(-48.0, elevationSumManager.getElevationLoss_m(), 0.01); + Assert.assertEquals(48.0, elevationSumManager.getElevationLoss_m(), 0.01); } @Test diff --git a/src/androidTest/java/de/dennisguse/opentracks/util/PressureSensorUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/util/PressureSensorUtilsTest.java index f3ee34a25..346c81520 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/util/PressureSensorUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/util/PressureSensorUtilsTest.java @@ -43,7 +43,7 @@ public class PressureSensorUtilsTest { // then assertEquals(0f, elevationGain_m, 0.01); - assertEquals(-15.0f, elevationLoss_m, 0.01); + assertEquals(15.0f, elevationLoss_m, 0.01); assertEquals(1016.80f, lastUsedPressureValue_hPa, 0.01); //Expect exponential smoothing } } \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/adapters/IntervalStatisticsAdapter.java b/src/main/java/de/dennisguse/opentracks/adapters/IntervalStatisticsAdapter.java index 59e8ac59c..af2477384 100644 --- a/src/main/java/de/dennisguse/opentracks/adapters/IntervalStatisticsAdapter.java +++ b/src/main/java/de/dennisguse/opentracks/adapters/IntervalStatisticsAdapter.java @@ -45,6 +45,7 @@ public class IntervalStatisticsAdapter extends ArrayAdapter parts = StringUtils.formatElevation(getContext(), elevationGain_m, metricUnits); + Pair parts; + + parts = StringUtils.formatElevation(getContext(), elevationGain_m, metricUnits); viewBinding.statsElevationGainValue.setText(parts.first); viewBinding.statsElevationGainUnit.setText(parts.second); + + parts = StringUtils.formatElevation(getContext(), elevationLoss_m, metricUnits); + viewBinding.statsElevationLossValue.setText(parts.first); + viewBinding.statsElevationLossUnit.setText(parts.second); } } } diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java index 67aa66ee1..e707ba93f 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java @@ -261,7 +261,7 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi /** * Tries to fetch most recent {@link SensorDataSet} from {@link de.dennisguse.opentracks.services.TrackRecordingService}. - * Also sets elevation gain. + * Also sets elevation gain and loss. */ private void updateSensorDataUI() { TrackRecordingServiceInterface trackRecordingService = trackRecordingServiceConnection.getServiceIfBound(); @@ -284,13 +284,14 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi sensorsAdapter.swapData(sensorDataList); setSpeedSensorData(sensorDataSet); } + //TODO Check if we can distribute the total elevation gain and loss via trackStatistics instead of doing some computation in the UI layer. setTotalElevationGain(trackRecordingService.getElevationGain_m()); + setTotalElevationLoss(trackRecordingService.getElevationLoss_m()); } } // Set elevation gain private void setTotalElevationGain(Float elevationGain_m) { - //TODO Check if we can distribute the total elevation gain via trackStatistics instead of doing some computation in the UI layer. boolean metricUnits = PreferencesUtils.isMetricUnits(getContext()); Float totalElevationGain = elevationGain_m; @@ -308,6 +309,25 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi viewBinding.statsElevationGainUnit.setText(parts.second); } + // Set elevation loss + private void setTotalElevationLoss(Float elevationLoss_m) { + boolean metricUnits = PreferencesUtils.isMetricUnits(getContext()); + + Float totalElevationLoss = elevationLoss_m; + + if (lastTrackStatistics != null && lastTrackStatistics.hasTotalElevationLoss()) { + if (elevationLoss_m == null) { + totalElevationLoss = lastTrackStatistics.getTotalElevationLoss(); + } else { + totalElevationLoss += lastTrackStatistics.getTotalElevationLoss(); + } + } + + Pair parts = StringUtils.formatElevation(getContext(), totalElevationLoss, metricUnits); + viewBinding.statsElevationLossValue.setText(parts.first); + viewBinding.statsElevationLossUnit.setText(parts.second); + } + private void setSpeedSensorData(SensorDataSet sensorDataSet) { if (sensorDataSet != null && sensorDataSet.getCyclingSpeed() != null) { SensorDataCycling.Speed data = sensorDataSet.getCyclingSpeed(); @@ -378,7 +398,7 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi viewBinding.statsMovingSpeedUnit.setText(parts.second); } - // Set elevation (gain) + // Set elevation gain and loss { // Make elevation visible? boolean showElevation = PreferencesUtils.isShowStatsElevation(getContext()); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KmlTrackWriter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KmlTrackWriter.java index cf0b7a867..3a2c21309 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KmlTrackWriter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KmlTrackWriter.java @@ -51,6 +51,7 @@ public class KmlTrackWriter implements TrackWriter { public static final String EXTENDED_DATA_TYPE_HEART_RATE = "heart_rate"; public static final String EXTENDED_DATA_TYPE_POWER = "power"; public static final String EXTENDED_DATA_TYPE_ELEVATION_GAIN = "elevation_gain"; + public static final String EXTENDED_DATA_TYPE_ELEVATION_LOSS = "elevation_loss"; private static final String MARKER_ICON = "http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png"; private static final String START_ICON = "http://maps.google.com/mapfiles/kml/paddle/grn-circle.png"; @@ -70,6 +71,7 @@ public class KmlTrackWriter implements TrackWriter { private final List cadenceList = new ArrayList<>(); private final List heartRateList = new ArrayList<>(); private final List elevationGainList = new ArrayList<>(); + private final List elevationLossList = new ArrayList<>(); private TrackPoint startTrackPoint; @@ -262,6 +264,9 @@ public class KmlTrackWriter implements TrackWriter { if (elevationGainList.size() > 0) { writeSimpleArrayData(elevationGainList, EXTENDED_DATA_TYPE_ELEVATION_GAIN); } + if (elevationLossList.size() > 0) { + writeSimpleArrayData(elevationLossList, EXTENDED_DATA_TYPE_ELEVATION_LOSS); + } } printWriter.println(""); printWriter.println(""); @@ -295,6 +300,9 @@ public class KmlTrackWriter implements TrackWriter { if (trackPoint.hasElevationGain()) { elevationGainList.add(trackPoint.getElevationGain()); } + if (trackPoint.hasElevationLoss()) { + elevationLossList.add(trackPoint.getElevationLoss()); + } } } } diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java index 3905fe4a7..759007b59 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java @@ -69,6 +69,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { private final ArrayList heartRateList = new ArrayList<>(); private final ArrayList powerList = new ArrayList<>(); private final ArrayList elevationGainList = new ArrayList<>(); + private final ArrayList elevationLossList = new ArrayList<>(); public KmlFileTrackImporter(Context context) { this(context, new ContentProviderUtils(context)); @@ -217,6 +218,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { cadenceList.clear(); powerList.clear(); elevationGainList.clear(); + elevationLossList.clear(); } /** @@ -242,6 +244,9 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { if (i < elevationGainList.size()) { trackPoint.setElevationGain(elevationGainList.get(i)); } + if (i < elevationLossList.size()) { + trackPoint.setElevationLoss(elevationLossList.get(i)); + } insertTrackPoint(trackPoint); } @@ -311,6 +316,9 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { case KmlTrackWriter.EXTENDED_DATA_TYPE_ELEVATION_GAIN: elevationGainList.add(value); break; + case KmlTrackWriter.EXTENDED_DATA_TYPE_ELEVATION_LOSS: + elevationLossList.add(value); + break; default: Log.w(TAG, "Data from extended data " + extendedDataType + " is not (yet) supported."); } diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index 6b9ad5ac1..14f14c35c 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -665,6 +665,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand try { if (elevationSumManager != null) { trackPoint.setElevationGain(elevationSumManager.getElevationGain_m()); + trackPoint.setElevationLoss(elevationSumManager.getElevationLoss_m()); elevationSumManager.reset(); } contentProviderUtils.insertTrackPoint(trackPoint, track.getId()); @@ -680,7 +681,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand voiceExecutor.update(); } - /** * Updates the recording track time. * @@ -718,6 +718,17 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand return elevationSumManager.getElevationGain_m(); } + /** + * Returns the relative elevation loss (since last trackpoint). + */ + Float getElevationLoss_m() { + if (elevationSumManager == null || !elevationSumManager.isConnected()) { + return null; + } + + return elevationSumManager.getElevationLoss_m(); + } + private void showNotification(boolean isGpsStarted) { if (isRecording()) { Intent intent = IntentUtils.newIntent(this, TrackRecordingActivity.class) diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java index 12a92ca0a..9882b59e4 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java @@ -104,6 +104,11 @@ class TrackRecordingServiceBinder extends android.os.Binder implements TrackReco return trackRecordingService.getElevationGain_m(); } + @Override + public Float getElevationLoss_m() { + return trackRecordingService.getElevationLoss_m(); + } + @VisibleForTesting @Override public void setRemoteSensorManager(BluetoothRemoteSensorManager remoteSensorManager) { diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java index b56a704f3..107fef395 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java @@ -78,6 +78,13 @@ public interface TrackRecordingServiceInterface { */ Float getElevationGain_m(); + /** + * Gets the current elevation loss. + * + * @return elevation loss in m or null. + */ + Float getElevationLoss_m(); + @VisibleForTesting void setRemoteSensorManager(BluetoothRemoteSensorManager remoteSensorManager); diff --git a/src/main/java/de/dennisguse/opentracks/services/sensors/ElevationSumManager.java b/src/main/java/de/dennisguse/opentracks/services/sensors/ElevationSumManager.java index f8ab382b9..12ea8ddd5 100644 --- a/src/main/java/de/dennisguse/opentracks/services/sensors/ElevationSumManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/sensors/ElevationSumManager.java @@ -112,6 +112,6 @@ public class ElevationSumManager implements SensorEventListener { lastSeenSensorValue_hPa = value_hPa; - Log.v(TAG, "elevation gain: " + elevationGain_m); + Log.v(TAG, "elevation gain: " + elevationGain_m + ", elevation loss: " + elevationLoss_m); } } diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatistics.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatistics.java index 42bd19f7b..f3420b846 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatistics.java @@ -45,6 +45,8 @@ public class TrackStatistics { private double maxSpeed_mps; // The total elevation gained (meters). private Float totalElevationGain_m = null; + // The total elevation lost (meters). + private Float totalElevationLoss_m = null; public TrackStatistics() { } @@ -63,6 +65,7 @@ public class TrackStatistics { maxSpeed_mps = other.maxSpeed_mps; elevationExtremities.set(other.elevationExtremities.getMin(), other.elevationExtremities.getMax()); totalElevationGain_m = other.totalElevationGain_m; + totalElevationLoss_m = other.totalElevationLoss_m; } /** @@ -91,6 +94,15 @@ public class TrackStatistics { totalElevationGain_m += other.totalElevationGain_m; } } + if (totalElevationLoss_m == null) { + if (other.totalElevationLoss_m != null) { + totalElevationLoss_m = other.totalElevationLoss_m; + } + } else { + if (other.totalElevationLoss_m != null) { + totalElevationLoss_m += other.totalElevationLoss_m; + } + } } /** @@ -257,6 +269,26 @@ public class TrackStatistics { totalElevationGain_m += gain_m; } + public boolean hasTotalElevationLoss() { + return totalElevationLoss_m != null; + } + + public @Nullable + Float getTotalElevationLoss() { + return totalElevationLoss_m; + } + + public void setTotalElevationLoss(float totalElevationLoss_m) { + this.totalElevationLoss_m = totalElevationLoss_m; + } + + public void addTotalElevationLoss(float loss_m) { + if (totalElevationLoss_m == null) { + totalElevationLoss_m = 0f; + } + totalElevationLoss_m += loss_m; + } + @NonNull @Override public String toString() { @@ -264,6 +296,7 @@ public class TrackStatistics { + "; Total Distance: " + getTotalDistance() + "; Total Time: " + getTotalTime() + "; Moving Time: " + getMovingTime() + "; Max Speed: " + getMaxSpeed() + "; Min Elevation: " + getMinElevation() + "; Max Elevation: " + getMaxElevation() - + "; Elevation Gain: " + getTotalElevationGain() + "}"; + + "; Elevation Gain: " + getTotalElevationGain() + + "; Elevation Loss: " + getTotalElevationLoss() + "}"; } } \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index 300833a50..96f7f0254 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -145,6 +145,12 @@ public class TrackStatisticsUpdater { Log.d(TAG, "elevation gain: " + trackPoint.getElevationGain()); } + //Get elevation loss + if (trackPoint.hasElevationLoss()) { + currentSegment.addTotalElevationLoss(trackPoint.getElevationLoss()); + Log.d(TAG, "elevation loss: " + trackPoint.getElevationLoss()); + } + if (lastTrackPoint == null || lastMovingTrackPoint == null) { lastTrackPoint = trackPoint; lastMovingTrackPoint = trackPoint; diff --git a/src/main/java/de/dennisguse/opentracks/util/PressureSensorUtils.java b/src/main/java/de/dennisguse/opentracks/util/PressureSensorUtils.java index bcc402131..be5e95394 100644 --- a/src/main/java/de/dennisguse/opentracks/util/PressureSensorUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/PressureSensorUtils.java @@ -36,7 +36,7 @@ public class PressureSensorUtils { } public float getElevationLoss_m() { - return elevationChange_m < 0 ? elevationChange_m : 0; + return elevationChange_m < 0 ? -1 * elevationChange_m : 0; } } @@ -65,7 +65,7 @@ public class PressureSensorUtils { // Limit elevation change by ELEVATION_CHANGE_DIFF and computes pressure value accordingly. ElevationChange elevationChange = new ElevationChange(currentSensorValue_hPa, elevationChange_m); - if (elevationChange.getElevationGain_m() > 0) { + if (elevationChange.getElevationChange_m() > 0) { return new ElevationChange(getBarometricPressure(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, lastSensorValue_m + ELEVATION_CHANGE_DIFF_M), ELEVATION_CHANGE_DIFF_M); } else { return new ElevationChange(getBarometricPressure(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, lastSensorValue_m - ELEVATION_CHANGE_DIFF_M), -1 * ELEVATION_CHANGE_DIFF_M); diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java index a56a42ed3..7ef57756c 100644 --- a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java @@ -25,6 +25,7 @@ public class IntervalStatistics { Interval interval = new Interval(); interval.gain_m += trackPoints.get(0).hasElevationGain() ? trackPoints.get(0).getElevationGain() : 0; + interval.loss_m += trackPoints.get(0).hasElevationLoss() ? trackPoints.get(0).getElevationLoss() : 0; for (int i = 1; i < trackPoints.size(); i++) { TrackPoint prevTrackPoint = trackPoints.get(i - 1); TrackPoint trackPoint = trackPoints.get(i); @@ -33,6 +34,7 @@ public class IntervalStatistics { interval.distance_m += prevTrackPoint.distanceTo(trackPoint); interval.time_ms += trackPoint.getTime() - prevTrackPoint.getTime(); interval.gain_m += trackPoint.hasElevationGain() ? trackPoint.getElevationGain() : 0; + interval.loss_m += trackPoint.hasElevationLoss() ? trackPoint.getElevationLoss() : 0; if (interval.distance_m >= distanceInterval_m) { float adjustFactor = distanceInterval_m / interval.distance_m; @@ -80,6 +82,7 @@ public class IntervalStatistics { private float distance_m = 0f; private float time_ms = 0f; private float gain_m = 0f; + private float loss_m = 0f; public Interval() {} @@ -87,12 +90,14 @@ public class IntervalStatistics { this.distance_m = distance_m; this.time_ms = time_ms; this.gain_m = 0f; + this.loss_m = 0f; } public Interval(Interval i) { distance_m = i.distance_m; time_ms = i.time_ms; gain_m = i.gain_m; + loss_m = i.loss_m; } public float getDistance_m() { @@ -117,5 +122,9 @@ public class IntervalStatistics { public float getGain_m() { return gain_m; } + + public float getLoss_m() { + return loss_m; + } } } diff --git a/src/main/res/drawable/ic_arrow_drop_down_24.xml b/src/main/res/drawable/ic_arrow_drop_down_24.xml new file mode 100644 index 000000000..ce583469c --- /dev/null +++ b/src/main/res/drawable/ic_arrow_drop_down_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/src/main/res/layout/interval_list_view.xml b/src/main/res/layout/interval_list_view.xml index 6aaa991c8..d1611f163 100644 --- a/src/main/res/layout/interval_list_view.xml +++ b/src/main/res/layout/interval_list_view.xml @@ -46,7 +46,7 @@ + android:text="@string/stats_elevation" /> diff --git a/src/main/res/layout/interval_stats_list_item.xml b/src/main/res/layout/interval_stats_list_item.xml index 121dd9db1..3e252c546 100644 --- a/src/main/res/layout/interval_stats_list_item.xml +++ b/src/main/res/layout/interval_stats_list_item.xml @@ -4,28 +4,48 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" + android:paddingTop="4dp" + android:paddingBottom="4dp" android:orientation="horizontal"> - + android:orientation="vertical"> + + + + + + \ No newline at end of file diff --git a/src/main/res/layout/statistics_recorded.xml b/src/main/res/layout/statistics_recorded.xml index 38ce32c43..5adafdafe 100644 --- a/src/main/res/layout/statistics_recorded.xml +++ b/src/main/res/layout/statistics_recorded.xml @@ -234,20 +234,20 @@ app:layout_constraintEnd_toStartOf="@+id/guideline3" app:layout_constraintTop_toBottomOf="@+id/stats_speed_barrier" /> - + + app:constraint_referenced_ids="stats_elevation_horizontal_line,stats_elevation_gain_label,stats_elevation_gain_value,stats_elevation_gain_unit,stats_elevation_loss_label,stats_elevation_loss_value,stats_elevation_loss_unit" /> @@ -265,6 +265,33 @@ style="@style/StatsUnit" app:layout_constraintBottom_toBottomOf="@+id/stats_elevation_gain_value" app:layout_constraintStart_toEndOf="@+id/stats_elevation_gain_value" + app:layout_constraintEnd_toStartOf="@+id/guideline2" + tools:text="m" /> + + + + + + @@ -274,7 +301,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierDirection="bottom" - app:constraint_referenced_ids="stats_elevation_gain_value" /> + app:constraint_referenced_ids="stats_elevation_gain_value,stats_elevation_loss_value" /> @@ -64,8 +64,8 @@ style="@style/StatsLargeLabel" android:text="@string/track_edit_activity_type_hint" app:layout_constrainedWidth="true" - app:layout_constraintStart_toEndOf="@+id/guideline2" - app:layout_constraintEnd_toStartOf="@+id/guideline3" + app:layout_constraintStart_toEndOf="@id/guideline2" + app:layout_constraintEnd_toStartOf="@id/guideline3" app:layout_constraintTop_toTopOf="parent" /> @@ -85,16 +85,16 @@ style="@style/StatsLargeLabel" android:text="@string/stats_total_time" app:layout_constrainedWidth="true" - app:layout_constraintStart_toEndOf="@+id/guideline" - app:layout_constraintEnd_toStartOf="@+id/guideline2" - app:layout_constraintTop_toBottomOf="@+id/stats_distance_value" /> + app:layout_constraintStart_toEndOf="@id/guideline" + app:layout_constraintEnd_toStartOf="@id/guideline2" + app:layout_constraintTop_toBottomOf="@id/stats_distance_value" /> @@ -103,18 +103,18 @@ style="@style/StatsLargeLabel" android:text="@string/stats_moving_time" app:layout_constrainedWidth="true" - app:layout_constraintStart_toEndOf="@+id/guideline2" - app:layout_constraintEnd_toStartOf="@+id/guideline3" - app:layout_constraintTop_toTopOf="@+id/stats_total_time_label" - app:layout_constraintBottom_toBottomOf="@+id/stats_total_time_label" /> + app:layout_constraintStart_toEndOf="@id/guideline2" + app:layout_constraintEnd_toStartOf="@id/guideline3" + app:layout_constraintTop_toTopOf="@id/stats_total_time_label" + app:layout_constraintBottom_toBottomOf="@id/stats_total_time_label" /> @@ -130,17 +130,17 @@ android:id="@+id/stats_speed_horizontal_line" style="@style/StatsHorizontalLine" android:layout_marginBottom="8dp" - app:layout_constraintStart_toEndOf="@+id/guideline" - app:layout_constraintEnd_toStartOf="@+id/guideline3" - app:layout_constraintTop_toBottomOf="@+id/stats_time_barrier" /> + app:layout_constraintStart_toEndOf="@id/guideline" + app:layout_constraintEnd_toStartOf="@id/guideline3" + app:layout_constraintTop_toBottomOf="@id/stats_time_barrier" /> @@ -149,17 +149,17 @@ style="@style/StatsSmallValue" android:value="@string/value_unknown" app:layout_constraintHorizontal_chainStyle="packed" - app:layout_constraintStart_toEndOf="@+id/guideline" - app:layout_constraintEnd_toStartOf="@+id/stats_speed_unit" - app:layout_constraintTop_toBottomOf="@+id/stats_speed_label" + app:layout_constraintStart_toEndOf="@id/guideline" + app:layout_constraintEnd_toStartOf="@id/stats_speed_unit" + app:layout_constraintTop_toBottomOf="@id/stats_speed_label" tools:text="30.00" /> @@ -167,8 +167,8 @@ android:id="@+id/stats_average_speed_label" style="@style/StatsSmallLabel" app:layout_constrainedWidth="true" - app:layout_constraintStart_toEndOf="@+id/guideline2" - app:layout_constraintEnd_toStartOf="@+id/guideline3" + app:layout_constraintStart_toEndOf="@id/guideline2" + app:layout_constraintEnd_toStartOf="@id/guideline3" app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line" tools:text="Avg. Speed" /> @@ -177,17 +177,17 @@ style="@style/StatsSmallValue" android:value="@string/value_unknown" app:layout_constraintHorizontal_chainStyle="packed" - app:layout_constraintStart_toEndOf="@+id/guideline2" - app:layout_constraintEnd_toStartOf="@+id/stats_average_speed_unit" - app:layout_constraintTop_toBottomOf="@+id/stats_average_speed_label" + app:layout_constraintStart_toEndOf="@id/guideline2" + app:layout_constraintEnd_toStartOf="@id/stats_average_speed_unit" + app:layout_constraintTop_toBottomOf="@id/stats_average_speed_label" tools:text="30.00" /> @@ -195,8 +195,8 @@ android:id="@+id/stats_max_speed_label" style="@style/StatsSmallLabel" app:layout_constrainedWidth="true" - app:layout_constraintStart_toEndOf="@+id/guideline" - app:layout_constraintEnd_toStartOf="@+id/guideline2" + app:layout_constraintStart_toEndOf="@id/guideline" + app:layout_constraintEnd_toStartOf="@id/guideline2" app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value" tools:text="Max. Speed" /> @@ -205,17 +205,17 @@ style="@style/StatsSmallValue" android:value="@string/value_unknown" app:layout_constraintHorizontal_chainStyle="packed" - app:layout_constraintStart_toEndOf="@+id/guideline" - app:layout_constraintEnd_toStartOf="@+id/stats_max_speed_unit" - app:layout_constraintTop_toBottomOf="@+id/stats_max_speed_label" + app:layout_constraintStart_toEndOf="@id/guideline" + app:layout_constraintEnd_toStartOf="@id/stats_max_speed_unit" + app:layout_constraintTop_toBottomOf="@id/stats_max_speed_label" tools:text="30.00" /> @@ -223,8 +223,8 @@ android:id="@+id/stats_moving_speed_label" style="@style/StatsSmallLabel" app:layout_constrainedWidth="true" - app:layout_constraintStart_toEndOf="@+id/guideline2" - app:layout_constraintEnd_toStartOf="@+id/guideline3" + app:layout_constraintStart_toEndOf="@id/guideline2" + app:layout_constraintEnd_toStartOf="@id/guideline3" app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value" tools:text="Max. Moving Speed" /> @@ -233,17 +233,17 @@ style="@style/StatsSmallValue" android:value="@string/value_unknown" app:layout_constraintHorizontal_chainStyle="packed" - app:layout_constraintStart_toEndOf="@+id/guideline2" - app:layout_constraintEnd_toStartOf="@+id/stats_moving_speed_unit" - app:layout_constraintTop_toBottomOf="@+id/stats_moving_speed_label" + app:layout_constraintStart_toEndOf="@id/guideline2" + app:layout_constraintEnd_toStartOf="@id/stats_moving_speed_unit" + app:layout_constraintTop_toBottomOf="@id/stats_moving_speed_label" tools:text="30.00" /> @@ -259,16 +259,16 @@ android:id="@+id/stats_elevation_horizontal_line" style="@style/StatsHorizontalLine" android:layout_marginBottom="8dp" - app:layout_constraintStart_toEndOf="@+id/guideline" - app:layout_constraintEnd_toStartOf="@+id/guideline3" - app:layout_constraintTop_toBottomOf="@+id/stats_speed_barrier" /> + app:layout_constraintStart_toEndOf="@id/guideline" + app:layout_constraintEnd_toStartOf="@id/guideline3" + app:layout_constraintTop_toBottomOf="@id/stats_speed_barrier" /> + app:constraint_referenced_ids="stats_elevation_horizontal_line,stats_elevation_current_label,stats_elevation_current_value,stats_elevation_current_unit,stats_elevation_gain_label,stats_elevation_gain_value,stats_elevation_gain_unit,stats_elevation_loss_label,stats_elevation_loss_value,stats_elevation_loss_unit" /> - + + + + + + + + @@ -339,16 +367,16 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierDirection="bottom" - app:constraint_referenced_ids="stats_elevation_current_value,stats_elevation_gain_value" /> + app:constraint_referenced_ids="stats_elevation_current_value,stats_elevation_gain_value,stats_elevation_loss_value" /> + app:layout_constraintStart_toEndOf="@id/guideline" + app:layout_constraintEnd_toStartOf="@id/guideline3" + app:layout_constraintTop_toBottomOf="@id/stats_elevation_barrier" /> @@ -374,17 +402,17 @@ style="@style/StatsSmallLabel" android:text="@string/stats_longitude" app:layout_constrainedWidth="true" - app:layout_constraintStart_toEndOf="@+id/guideline2" - app:layout_constraintEnd_toStartOf="@+id/guideline3" + app:layout_constraintStart_toEndOf="@id/guideline2" + app:layout_constraintEnd_toStartOf="@id/guideline3" app:layout_constraintTop_toBottomOf="@id/stats_coordinate_horizontal_line" /> @@ -400,17 +428,17 @@ android:id="@+id/stats_sensor_horizontal_line" style="@style/StatsHorizontalLine" android:layout_marginBottom="8dp" - app:layout_constraintStart_toEndOf="@+id/guideline" - app:layout_constraintEnd_toStartOf="@+id/guideline3" - app:layout_constraintTop_toBottomOf="@+id/stats_location_barrier" /> + app:layout_constraintStart_toEndOf="@id/guideline" + app:layout_constraintEnd_toStartOf="@id/guideline3" + app:layout_constraintTop_toBottomOf="@id/stats_location_barrier" /> diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index e4f56c08b..f0e102ee1 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -176,6 +176,7 @@ limitations under the License. Average pace: %1$s min/km (%2$s min/mi) Average speed: %1$.2f km/h (%2$.1f mi/h) Elevation gain: %1$d m (%2$d ft) + Elevation loss: %1$d m (%2$d ft) Elevation (ft) Elevation (m) Fastest pace: %1$s min/km (%2$s min/mi) @@ -447,6 +448,7 @@ limitations under the License. Elevation Fastest pace Gain + Loss Grade Latitude Longitude