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