Refactored stats_content layout to contain all content (not use include).

This commit is contained in:
Dennis Guse
2019-09-12 17:38:25 +02:00
parent b5cb47a0c7
commit 42b3a5dfc9
11 changed files with 471 additions and 419 deletions
+2 -1
View File
@@ -10,4 +10,5 @@ Developer:
- Fixed (some) test cases
- Removed unused parcelable functionality
- Major cleanup and reformatting
- Do not use broadcast for app to widget communication
- Do not use broadcast for app to widget communication
- stats_content.xml is does not include other files
@@ -262,8 +262,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
}
/**
* Resumes the trackDataHub. Needs to be synchronized because trackDataHub can
* be accessed by multiple threads.
* Resumes the trackDataHub.
* Needs to be synchronized because trackDataHub can be accessed by multiple threads.
*/
private synchronized void resumeTrackDataHub() {
trackDataHub = ((TrackDetailActivity) getActivity()).getTrackDataHub();
@@ -273,8 +273,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
}
/**
* Pauses the trackDataHub. Needs to be synchronized because trackDataHub can
* be accessed by multiple threads.
* Pauses the trackDataHub.
* Needs to be synchronized because trackDataHub can be accessed by multiple threads.
*/
private synchronized void pauseTrackDataHub() {
trackDataHub.unregisterTrackDataListener(this);
@@ -282,16 +282,16 @@ public class StatsFragment extends Fragment implements TrackDataListener {
}
/**
* Returns true if the selected track is recording. Needs to be synchronized
* because trackDataHub can be accessed by multiple threads.
* Returns true if the selected track is recording.
* Needs to be synchronized because trackDataHub can be accessed by multiple threads.
*/
private synchronized boolean isSelectedTrackRecording() {
return trackDataHub != null && trackDataHub.isSelectedTrackRecording();
}
/**
* Returns true if the selected track is paused. Needs to be synchronized
* because trackDataHub can be accessed by multiple threads.
* Returns true if the selected track is paused.
* Needs to be synchronized because trackDataHub can be accessed by multiple threads.
*/
private synchronized boolean isSelectedTrackPaused() {
return trackDataHub != null && trackDataHub.isSelectedTrackPaused();
@@ -310,7 +310,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
sensorDataSet = trackRecordingService.getSensorData();
}
StatsUtils.setSensorData(getActivity(), getActivity(), sensorDataSet, isSelectedTrackRecording());
StatsUtils.setSensorData(getActivity(), sensorDataSet, isSelectedTrackRecording());
}
/**
@@ -24,8 +24,6 @@ import android.view.View;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.Locale;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.services.sensors.RemoteSensorManager;
@@ -58,54 +56,78 @@ public class StatsUtils {
boolean reportSpeed = PreferencesUtils.isReportSpeed(context);
// Set speed/pace
View speed = getView(activity, view, R.id.stats_speed);
speed.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
View speedContainer = activity.findViewById(R.id.stats_speed);
speedContainer.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
if (isRecording) {
double value = isRecording && location != null && location.hasSpeed() ? location.getSpeed() : Double.NaN;
setSpeed(context, speed, R.string.stats_speed, R.string.stats_pace, value, metricUnits, reportSpeed);
TextView speedLabel = activity.findViewById(R.id.stats_speed_label);
speedLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace);
double speed = location != null && location.hasSpeed() ? location.getSpeed() : Double.NaN;
Pair<String, String> parts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
TextView speedValue = activity.findViewById(R.id.stats_speed_value);
speedValue.setText(parts.first);
TextView speedUnit = activity.findViewById(R.id.stats_speed_unit);
speedUnit.setText(parts.second);
}
// Set elevation
boolean showGradeElevation = PreferencesUtils.getBoolean(context, R.string.stats_show_grade_elevation_key, PreferencesUtils.STATS_SHOW_ELEVATION_DEFAULT) && isRecording;
View elevation = getView(activity, view, R.id.stats_elevation);
elevation.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE);
View elevationContainer = getView(activity, view, R.id.stats_elevation);
elevationContainer.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE);
if (showGradeElevation) {
double altitude = location != null && location.hasAltitude() ? location.getAltitude() : Double.NaN;
setElevationValue(context, elevation, -1, altitude, metricUnits);
Pair<String, String> parts = formatElevation(context, altitude, metricUnits);
TextView elevationValue = activity.findViewById(R.id.stats_elevation_current_value);
elevationValue.setText(parts.first);
TextView elevationUnit = activity.findViewById(R.id.stats_elevation_current_unit);
elevationUnit.setText(parts.second);
}
// Set coordinate
boolean showCoordinate = isRecording && PreferencesUtils.getBoolean(context, R.string.stats_show_coordinate_key, PreferencesUtils.STATS_SHOW_COORDINATE_DEFAULT);
View coordinateSeparator = getView(activity, view, R.id.stats_coordinate_separator);
coordinateSeparator.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
View coordinateContainer = getView(activity, view, R.id.stats_coordinate_container);
if (coordinateSeparator != null) {
coordinateSeparator.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
}
coordinateContainer.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
if (showCoordinate) {
double latitude = location != null ? location.getLatitude() : Double.NaN;
String latitudeText = Double.isNaN(latitude) || Double.isInfinite(latitude) ? activity.getString(R.string.value_unknown) : StringUtils.formatCoordinate(latitude);
TextView latitudeValue = activity.findViewById(R.id.stats_latitude_value);
latitudeValue.setText(latitudeText);
double longitude = location != null ? location.getLongitude() : Double.NaN;
setCoordinateValue(context, getView(activity, view, R.id.stats_latitude), R.string.stats_latitude, latitude);
setCoordinateValue(context, getView(activity, view, R.id.stats_longitude), R.string.stats_longitude, longitude);
String longitudeText = Double.isNaN(longitude) || Double.isInfinite(longitude) ? activity.getString(R.string.value_unknown) : StringUtils.formatCoordinate(longitude);
TextView longitudeValue = activity.findViewById(R.id.stats_longitude_value);
longitudeValue.setText(longitudeText);
}
}
public static void setSensorData(Context context, Activity activity, SensorDataSet sensorDataSet, boolean isRecording) {
// SensorDataSet: heart rate
public static void setSensorData(Activity activity, SensorDataSet sensorDataSet, boolean isRecording) {
// heart rate
int isVisible = View.VISIBLE;
if (!isRecording || PreferencesUtils.BLUETOOTH_SENSOR_DEFAULT.equals(PreferencesUtils.getString(context, R.string.bluetooth_sensor_key, PreferencesUtils.BLUETOOTH_SENSOR_DEFAULT))) {
if (!isRecording || PreferencesUtils.BLUETOOTH_SENSOR_DEFAULT.equals(PreferencesUtils.getString(activity, R.string.bluetooth_sensor_key, PreferencesUtils.BLUETOOTH_SENSOR_DEFAULT))) {
isVisible = View.INVISIBLE;
}
getView(activity, null, R.id.stats_sensor_container).setVisibility(isVisible);
activity.findViewById(R.id.stats_sensor_container).setVisibility(isVisible);
View viewValue = getView(activity, null, R.id.stats_sensor_heart_rate_value);
View viewSensor = getView(activity, null, R.id.stats_sensor_heart_rate_sensor);
if (isRecording) {
setHeartRateData(context, viewValue, viewSensor, sensorDataSet);
TextView heartRateValue = activity.findViewById(R.id.stats_sensor_heart_rate_value);
TextView heartRateSensor = activity.findViewById(R.id.stats_sensor_heart_rate_sensor_value);
String heartRate = activity.getString(R.string.value_unknown);
String sensor = activity.getString(R.string.value_unknown);
if (sensorDataSet != null && sensorDataSet.hasHeartRate() && sensorDataSet.isRecent(RemoteSensorManager.MAX_SENSOR_DATE_SET_AGE)) {
heartRate = StringUtils.formatDecimal(sensorDataSet.getHeartRate(), 0);
sensor = sensorDataSet.getSensorName();
}
heartRateValue.setText(heartRate);
heartRateSensor.setText(sensor);
}
}
@@ -116,7 +138,8 @@ public class StatsUtils {
* @param totalTime the total time
*/
public static void setTotalTimeValue(Activity activity, long totalTime) {
setTimeValue(activity, activity.findViewById(R.id.stats_total_time), R.string.stats_total_time, totalTime);
TextView totalTimeValue = activity.findViewById(R.id.stats_total_time_value);
totalTimeValue.setText(StringUtils.formatElapsedTime(totalTime));
}
/**
@@ -133,205 +156,145 @@ public class StatsUtils {
boolean reportSpeed = PreferencesUtils.isReportSpeed(context);
// Set total distance
double totalDistance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance();
setDistanceValue(context, getView(activity, view, R.id.stats_distance), totalDistance, metricUnits);
{
double totalDistance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance();
Pair<String, String> parts = StringUtils.getDistanceParts(context, totalDistance, metricUnits);
TextView distanceValue = activity.findViewById(R.id.stats_distance_value);
distanceValue.setText(parts.first);
TextView distanceUnit = activity.findViewById(R.id.stats_distance_unit);
distanceUnit.setText(parts.second);
}
// Set activity type
getView(activity, null, R.id.stats_activity_type_label).setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
{
activity.findViewById(R.id.stats_activity_type_label).setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
Spinner spinner = (Spinner) getView(activity, view, R.id.stats_activity_type_icon);
spinner.setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
if (trackIconValue != null) {
TrackIconUtils.setIconSpinner(spinner, trackIconValue);
Spinner spinner = (Spinner) getView(activity, view, R.id.stats_activity_type_icon);
spinner.setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
if (trackIconValue != null) {
TrackIconUtils.setIconSpinner(spinner, trackIconValue);
}
}
// Set total time
setTimeValue(context, getView(activity, view, R.id.stats_total_time), R.string.stats_total_time, tripStatistics != null ? tripStatistics.getTotalTime() : -1L);
// Set time
if (tripStatistics != null) {
setTotalTimeValue(activity, tripStatistics.getTotalTime());
// Set moving time
setTimeValue(context, getView(activity, view, R.id.stats_moving_time), R.string.stats_moving_time, tripStatistics != null ? tripStatistics.getMovingTime() : -1L);
TextView movingTimeValue = activity.findViewById(R.id.stats_moving_time_value);
movingTimeValue.setText(StringUtils.formatElapsedTime(tripStatistics.getMovingTime()));
}
// Set average speed/pace
double averageSpeed = tripStatistics != null ? tripStatistics.getAverageSpeed() : Double.NaN;
setSpeed(context, getView(activity, view, R.id.stats_average_speed), R.string.stats_average_speed, R.string.stats_average_pace, averageSpeed, metricUnits, reportSpeed);
{
double speed = tripStatistics != null ? tripStatistics.getAverageSpeed() : Double.NaN;
TextView speedLabel = activity.findViewById(R.id.stats_average_speed_label);
speedLabel.setText(reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
Pair<String, String> parts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
TextView speedValue = activity.findViewById(R.id.stats_average_speed_value);
speedValue.setText(parts.first);
TextView speedUnit = activity.findViewById(R.id.stats_average_speed_unit);
speedUnit.setText(parts.second);
}
// Set max speed/pace
double maxSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed();
setSpeed(context, getView(activity, view, R.id.stats_max_speed), R.string.stats_max_speed, R.string.stats_fastest_pace, maxSpeed, metricUnits, reportSpeed);
{
double speed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed();
// Set average moving speed/pace
double averageMovingSpeed = tripStatistics != null ? tripStatistics.getAverageMovingSpeed() : Double.NaN;
setSpeed(context, getView(activity, view, R.id.stats_average_moving_speed), R.string.stats_average_moving_speed, R.string.stats_average_moving_pace, averageMovingSpeed, metricUnits, reportSpeed);
TextView speedLabel = activity.findViewById(R.id.stats_max_speed_label);
speedLabel.setText(reportSpeed ? R.string.stats_max_speed : R.string.stats_fastest_pace);
// Set grade/elevation
boolean showElevation = PreferencesUtils.getBoolean(context, R.string.stats_show_grade_elevation_key, PreferencesUtils.STATS_SHOW_ELEVATION_DEFAULT);
View gradeElevationSeparator = getView(activity, view, R.id.stats_elevation_separator);
gradeElevationSeparator.setVisibility(showElevation ? View.VISIBLE : View.GONE);
View gradeElevationContainer = getView(activity, view, R.id.stats_elevation_container);
gradeElevationContainer.setVisibility(showElevation ? View.VISIBLE : View.GONE);
if (showElevation) {
// Set elevation
double minElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation();
setElevationValue(context, getView(activity, view, R.id.stats_elevation_min), R.string.stats_min, minElevation, metricUnits);
double maxElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation();
setElevationValue(context, getView(activity, view, R.id.stats_elevation_max), R.string.stats_max, maxElevation, metricUnits);
Pair<String, String> parts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
TextView speedValue = activity.findViewById(R.id.stats_max_speed_value);
speedValue.setText(parts.first);
TextView speedUnit = activity.findViewById(R.id.stats_max_speed_unit);
speedUnit.setText(parts.second);
}
}
/**
* Sets speed.
*
* @param context the context
* @param view the containing view
* @param speedLabelId the speed label id
* @param paceLabelId the pace label id
* @param speed the speed in meters per second
* @param metricUnits true if metric units
* @param reportSpeed true if report speed
*/
private static void setSpeed(Context context, View view, int speedLabelId, int paceLabelId, double speed, boolean metricUnits, boolean reportSpeed) {
Pair<String, String> parts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
setItem(context, view, reportSpeed ? speedLabelId : paceLabelId, parts.first, parts.second);
}
// Set average speed/pace
{
double speed = tripStatistics != null ? tripStatistics.getAverageSpeed() : Double.NaN;
/**
* Sets distance value.
*
* @param context the context
* @param view the containing view
* @param distance the distance in meters
* @param metricUnits true if metric units
*/
private static void setDistanceValue(Context context, View view, double distance, boolean metricUnits) {
Pair<String, String> parts = StringUtils.getDistanceParts(context, distance, metricUnits);
setItem(context, view, R.string.stats_distance, parts.first, parts.second);
}
TextView speedLabel = activity.findViewById(R.id.stats_average_speed_label);
speedLabel.setText(reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
/**
* Sets a time value.
*
* @param context the context
* @param view the containing view
* @param labelId the label id
* @param time the time
*/
private static void setTimeValue(Context context, View view, int labelId, long time) {
String value = time == -1L ? null : StringUtils.formatElapsedTime(time);
setItem(context, view, labelId, value, null);
Pair<String, String> parts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
TextView speedValue = activity.findViewById(R.id.stats_average_speed_value);
speedValue.setText(parts.first);
TextView speedUnit = activity.findViewById(R.id.stats_average_speed_unit);
speedUnit.setText(parts.second);
}
// Set moving speed/pace
{
double speed = tripStatistics != null ? tripStatistics.getAverageMovingSpeed() : Double.NaN;
TextView speedLabel = activity.findViewById(R.id.stats_moving_speed_label);
speedLabel.setText(reportSpeed ? R.string.stats_average_moving_speed : R.string.stats_average_moving_pace);
Pair<String, String> parts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
TextView speedValue = activity.findViewById(R.id.stats_moving_speed_value);
speedValue.setText(parts.first);
TextView speedUnit = activity.findViewById(R.id.stats_moving_speed_unit);
speedUnit.setText(parts.second);
}
// Set elevation
{
boolean showElevation = PreferencesUtils.getBoolean(context, R.string.stats_show_grade_elevation_key, PreferencesUtils.STATS_SHOW_ELEVATION_DEFAULT);
View gradeElevationSeparator = getView(activity, view, R.id.stats_elevation_separator);
gradeElevationSeparator.setVisibility(showElevation ? View.VISIBLE : View.GONE);
View gradeElevationContainer = getView(activity, view, R.id.stats_elevation_container);
gradeElevationContainer.setVisibility(showElevation ? View.VISIBLE : View.GONE);
if (showElevation) {
{
double elevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation();
Pair<String, String> parts = formatElevation(context, elevation, metricUnits);
TextView elevationValue = activity.findViewById(R.id.stats_elevation_min_value);
elevationValue.setText(parts.first);
TextView elevationUnit = activity.findViewById(R.id.stats_elevation_min_unit);
elevationUnit.setText(parts.second);
}
{
double elevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation();
Pair<String, String> parts = formatElevation(context, elevation, metricUnits);
TextView elevationValue = activity.findViewById(R.id.stats_elevation_max_value);
elevationValue.setText(parts.first);
TextView elevationUnit = activity.findViewById(R.id.stats_elevation_max_unit);
elevationUnit.setText(parts.second);
}
}
}
}
/**
* Sets an elevation value.
*
* @param context the context
* @param view the containing view
* @param labelId the label id
* @param elevation the elevation in meters
* @param metricUnits true if metric units
* @return the formatted elevation (or null) and it's unit as {@link Pair}
*/
private static void setElevationValue(Context context, View view, int labelId, double elevation, boolean metricUnits) {
String value;
String unit;
if (Double.isNaN(elevation) || Double.isInfinite(elevation)) {
value = null;
unit = null;
} else {
// TODO Move to StringUtils
private static Pair<String, String> formatElevation(Context context, double elevation, boolean metricUnits) {
String value = context.getString(R.string.value_unknown);
String unit = context.getString(metricUnits ? R.string.unit_meter : R.string.unit_feet);
if (!Double.isNaN(elevation) && !Double.isInfinite(elevation)) {
if (metricUnits) {
value = StringUtils.formatDecimal(elevation);
unit = context.getString(R.string.unit_meter);
} else {
elevation *= UnitConversions.M_TO_FT;
value = StringUtils.formatDecimal(elevation);
unit = context.getString(R.string.unit_feet);
value = StringUtils.formatDecimal(elevation * UnitConversions.M_TO_FT);
}
}
setItem(context, view, labelId, value, unit);
}
/**
* Sets a grade value.
*
* @param context the context
* @param view the containing view
* @param labelId the label id
* @param grade the grade in fraction between 0 and 1
*/
private static void setGradeValue(Context context, View view, int labelId, double grade) {
String value = Double.isNaN(grade) || Double.isInfinite(grade) ? null : String.format(Locale.getDefault(), GRADE_FORMAT, Math.round(grade * 100));
setItem(context, view, labelId, value, GRADE_PERCENTAGE);
}
/**
* Sets a coordinate value.
*
* @param context the context
* @param view the containing view
* @param labelId the label id
* @param coordinate the coordinate in degrees
*/
private static void setCoordinateValue(Context context, View view, int labelId, double coordinate) {
String value = Double.isNaN(coordinate) || Double.isInfinite(coordinate) ? null : StringUtils.formatCoordinate(coordinate);
setItem(context, view, labelId, value, null);
}
/**
* Sets a heart rate value (sensor)
*
* @param context the context
* @param viewValue the containing view
* @param sensorDataSet the sensorDataSet
*/
private static void setHeartRateData(Context context, View viewValue, View viewSensor, SensorDataSet sensorDataSet) {
String heartRate = context.getString(R.string.value_unknown);
String sensor = context.getString(R.string.value_unknown);
if (sensorDataSet != null && sensorDataSet.hasHeartRate() && sensorDataSet.isRecent(RemoteSensorManager.MAX_SENSOR_DATE_SET_AGE)) {
heartRate = StringUtils.formatDecimal(sensorDataSet.getHeartRate(), 0);
sensor = sensorDataSet.getSensorName();
}
setItem(context, viewValue, R.string.sensor_state_heart_rate, heartRate, context.getString(R.string.sensor_unit_beats_per_minute));
setItem(context, viewSensor, R.string.settings_sensor_bluetooth_sensor, sensor, null);
}
/**
* Sets an item.
*
* @param context the context
* @param view the containing view
* @param labelId the label id. -1 to hide the label
* @param value the value, can be null
* @param unit the unit. Null to hide the unit
*/
private static void setItem(Context context, View view, int labelId, CharSequence value, CharSequence unit) {
TextView labelTextView = view.findViewById(R.id.stats_label);
if (labelTextView != null) {
if (labelId == -1) {
labelTextView.setVisibility(View.GONE);
} else {
labelTextView.setVisibility(View.VISIBLE);
labelTextView.setText(labelId);
}
}
TextView valueTextView = view.findViewById(R.id.stats_value);
TextView unitTextView = view.findViewById(R.id.stats_unit);
if (valueTextView == null || unitTextView == null) {
return;
}
if (value == null) {
value = context.getString(R.string.value_unknown);
unitTextView.setVisibility(View.GONE);
} else {
if (unit == null) {
unitTextView.setVisibility(View.GONE);
} else {
unitTextView.setVisibility(View.VISIBLE);
unitTextView.setText(unit);
}
}
valueTextView.setText(value);
return new Pair<>(value, unit);
}
/**
@@ -193,8 +193,9 @@ public class StringUtils {
}
String unitString = context.getString(unitId);
if (Double.isNaN(speed_mps) || Double.isInfinite(speed_mps)) {
return new Pair<>(null, unitString);
speed_mps = 0;
}
speed_mps *= UnitConversions.MS_TO_KMH;
+6 -9
View File
@@ -15,18 +15,15 @@ limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/StatsLargeItemContainer">
<!-- Label -->
<TextView
android:id="@+id/stats_activity_type_label"
style="@style/StatsLargeLabel"
android:text="@string/track_edit_activity_type_hint" />
<!-- Value container -->
<LinearLayout style="@style/StatsLargeValueContainer">
<Spinner
android:id="@+id/stats_activity_type_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp" />
</LinearLayout>
<Spinner
android:id="@+id/stats_activity_type_icon"
style="@style/StatsLargeValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
+292 -56
View File
@@ -18,57 +18,163 @@ limitations under the License.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Distance -->
<LinearLayout style="@style/StatsLargeItemContainer">
<include
android:id="@+id/stats_distance"
layout="@layout/stats_large_item" />
<TextView
style="@style/StatsLargeLabel"
android:text="@string/stats_distance" />
<LinearLayout style="@style/StatsLargeValueContainer">
<TextView
android:id="@+id/stats_distance_value"
style="@style/StatsLargeValue"
android:value="@string/value_unknown" />
<TextView
android:id="@+id/stats_distance_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
<!-- Activity type -->
<include
android:id="@+id/stats_activity_type"
layout="@layout/stats_activity_type" />
</LinearLayout>
<!-- Total time and moving time -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/stats_total_time"
layout="@layout/stats_large_item" />
<!-- Total time -->
<LinearLayout style="@style/StatsLargeItemContainer">
<include
android:id="@+id/stats_moving_time"
layout="@layout/stats_large_item" />
<TextView
style="@style/StatsLargeLabel"
android:text="@string/stats_total_time" />
<TextView
android:id="@+id/stats_total_time_value"
style="@style/StatsLargeValue" />
</LinearLayout>
<!-- Moving time -->
<LinearLayout style="@style/StatsLargeItemContainer">
<TextView
style="@style/StatsLargeLabel"
android:text="@string/stats_moving_time" />
<TextView
android:id="@+id/stats_moving_time_value"
style="@style/StatsLargeValue"
android:value="@string/value_unknown" />
</LinearLayout>
</LinearLayout>
<!-- Horizontal line -->
<View style="@style/StatsHorizontalLine" />
<!-- Speed and average speed -->
<!-- Speed/pace and average -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
<!-- Speed/pace -->
<LinearLayout
android:id="@+id/stats_speed"
layout="@layout/stats_small_item" />
style="@style/StatsSmallItemContainer">
<include
android:id="@+id/stats_average_speed"
layout="@layout/stats_small_item" />
<TextView
android:id="@+id/stats_speed_label"
style="@style/StatsSmallLabel" />
<LinearLayout style="@style/StatsSmallValueContainer">
<TextView
android:id="@+id/stats_speed_value"
style="@style/StatsSmallValue"
android:value="@string/value_unknown" />
<TextView
android:id="@+id/stats_speed_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
<!-- Average -->
<LinearLayout style="@style/StatsSmallItemContainer">
<TextView
android:id="@+id/stats_average_speed_label"
style="@style/StatsSmallLabel" />
<LinearLayout style="@style/StatsSmallValueContainer">
<TextView
android:id="@+id/stats_average_speed_value"
style="@style/StatsSmallValue"
android:value="@string/value_unknown" />
<TextView
android:id="@+id/stats_average_speed_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- Max speed and average moving speed -->
<!-- Speed max and moving -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/stats_max_speed"
layout="@layout/stats_small_item" />
<!-- Speed max -->
<TextView
android:id="@+id/stats_max_speed_label"
style="@style/StatsSmallLabel" />
<LinearLayout style="@style/StatsSmallItemContainer">
<include
android:id="@+id/stats_average_moving_speed"
layout="@layout/stats_small_item" />
<LinearLayout style="@style/StatsSmallValueContainer">
<TextView
android:id="@+id/stats_max_speed_value"
style="@style/StatsSmallValue"
android:value="@string/value_unknown" />
<TextView
android:id="@+id/stats_max_speed_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
<!-- Speed moving -->
<LinearLayout style="@style/StatsSmallItemContainer">
<TextView
android:id="@+id/stats_moving_speed_label"
style="@style/StatsSmallLabel" />
<LinearLayout style="@style/StatsSmallValueContainer">
<TextView
android:id="@+id/stats_moving_speed_value"
style="@style/StatsSmallValue"
android:value="@string/value_unknown" />
<TextView
android:id="@+id/stats_moving_speed_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- Horizontal line -->
<View
android:id="@+id/stats_elevation_separator"
style="@style/StatsHorizontalLine" />
@@ -77,12 +183,13 @@ limitations under the License.
android:id="@+id/stats_elevation_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout style="@style/StatsSmallGroupContainer">
<!-- This is a placeholder -->
</LinearLayout>
<!-- Elevation -->
<LinearLayout style="@style/StatsSmallGroupContainer">
<!-- Elevation label -->
<TextView
style="@style/StatsSmallLabel"
android:text="@string/stats_elevation" />
@@ -91,67 +198,196 @@ limitations under the License.
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<!-- Elevation -->
<include
<!-- Current elevation -->
<TableRow
android:id="@+id/stats_elevation"
layout="@layout/stats_small_group_item" />
<!-- Elevation gain -->
<!-- TODO DISABLED AS computation from GPS is not precise enough, go for getAltitude(RemoteSensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure) -->
<!--<include-->
<!--android:id="@+id/stats_elevation_gain"-->
<!--layout="@layout/stats_small_group_item" />-->
<include
android:id="@+id/stats_elevation_min"
layout="@layout/stats_small_group_item" />
<include
android:id="@+id/stats_elevation_max"
layout="@layout/stats_small_group_item" />
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
style="@style/StatsSmallValueContainer"
android:layout_gravity="left|bottom">
<TextView
style="@style/StatsSmallValue"
android:visibility="invisible" />
<TextView
android:id="@+id/stats_elevation_current_label"
style="@style/StatsSmallLabel"
android:paddingLeft="8dp" />
</LinearLayout>
<LinearLayout
style="@style/StatsSmallValueContainer"
android:layout_gravity="left|bottom">
<TextView
android:id="@+id/stats_elevation_current_value"
style="@style/StatsSmallValue"
android:value="@string/value_unknown" />
<TextView
android:id="@+id/stats_elevation_current_unit"
style="@style/StatsUnit" />
</LinearLayout>
</TableRow>
<!-- Minimal elevation -->
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
style="@style/StatsSmallValueContainer"
android:layout_gravity="right|bottom">
<TextView
android:id="@+id/stats_elevation_min_value"
style="@style/StatsSmallValue"
android:value="@string/value_unknown" />
<TextView
android:id="@+id/stats_elevation_min_unit"
style="@style/StatsUnit" />
</LinearLayout>
<LinearLayout
style="@style/StatsSmallValueContainer"
android:layout_gravity="left|bottom">
<TextView
style="@style/StatsSmallValue"
android:visibility="invisible" />
<TextView
style="@style/StatsSmallLabel"
android:layout_gravity="bottom"
android:paddingLeft="8dp"
android:text="@string/stats_min" />
</LinearLayout>
</TableRow>
<!-- Maximal elevation -->
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
style="@style/StatsSmallValueContainer"
android:layout_gravity="right|bottom">
<TextView
android:id="@+id/stats_elevation_max_value"
style="@style/StatsSmallValue" />
<TextView
android:id="@+id/stats_elevation_max_unit"
style="@style/StatsUnit" />
</LinearLayout>
<LinearLayout
style="@style/StatsSmallValueContainer"
android:layout_gravity="left|bottom">
<TextView
style="@style/StatsSmallValue"
android:visibility="invisible" />
<TextView
style="@style/StatsSmallLabel"
android:layout_gravity="bottom"
android:paddingLeft="8dp"
android:text="@string/stats_max" />
</LinearLayout>
</TableRow>
</TableLayout>
</LinearLayout>
</LinearLayout>
<!-- Horizontal line -->
<View
android:id="@+id/stats_coordinate_separator"
style="@style/StatsHorizontalLine" />
<!-- Latitude and longitude -->
<LinearLayout
android:id="@+id/stats_coordinate_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/stats_latitude"
layout="@layout/stats_small_item" />
<LinearLayout style="@style/StatsSmallItemContainer">
<include
android:id="@+id/stats_longitude"
layout="@layout/stats_small_item" />
<TextView
style="@style/StatsSmallLabel"
android:text="@string/stats_latitude" />
<TextView
android:id="@+id/stats_latitude_value"
style="@style/StatsSmallValue" />
</LinearLayout>
<LinearLayout style="@style/StatsSmallItemContainer">
<TextView
style="@style/StatsSmallLabel"
android:text="@string/stats_longitude" />
<TextView
android:id="@+id/stats_longitude_value"
style="@style/StatsSmallValue"
android:value="@string/value_unknown" />
</LinearLayout>
</LinearLayout>
<!-- Sensor data: heart rate-->
<View
android:id="@+id/stats_sensor_separator"
style="@style/StatsHorizontalLine" />
<!-- Sensor data: heart rate-->
<LinearLayout
android:id="@+id/stats_sensor_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/stats_sensor_heart_rate_value"
layout="@layout/stats_large_item" />
<LinearLayout style="@style/StatsLargeItemContainer">
<TextView
android:id="@+id/stats_sensor_heart_rate_label"
style="@style/StatsLargeLabel"
android:text="@string/sensor_state_heart_rate" />
<LinearLayout style="@style/StatsLargeValueContainer">
<TextView
android:id="@+id/stats_sensor_heart_rate_value"
style="@style/StatsLargeValue"
android:value="@string/value_unknown" />
<TextView
style="@style/StatsUnit"
android:text="@string/sensor_unit_beats_per_minute" />
</LinearLayout>
</LinearLayout>
<LinearLayout style="@style/StatsSmallGroupContainer">
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<TextView
style="@style/StatsSmallLabel"
android:text="@string/settings_sensor_bluetooth_sensor" />
<TextView
android:id="@+id/stats_sensor_heart_rate_sensor_value"
style="@style/StatsTinyValue"
android:value="@string/value_unknown" />
<include
android:id="@+id/stats_sensor_heart_rate_sensor"
layout="@layout/stats_tiny_item" />
</TableLayout>
</LinearLayout>
</LinearLayout>
</merge>
-33
View File
@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/StatsLargeItemContainer">
<!-- Label -->
<TextView
android:id="@+id/stats_label"
style="@style/StatsLargeLabel" />
<!-- Value container -->
<LinearLayout style="@style/StatsLargeValueContainer">
<!-- Value -->
<TextView
android:id="@+id/stats_value"
style="@style/StatsLargeValue" />
<!-- Unit -->
<TextView
android:id="@+id/stats_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!-- Value container -->
<LinearLayout
style="@style/StatsSmallValueContainer"
android:layout_gravity="right|bottom">
<!-- Value -->
<TextView
android:id="@+id/stats_value"
style="@style/StatsSmallValue" />
<!-- Unit -->
<TextView
android:id="@+id/stats_unit"
style="@style/StatsUnit" />
</LinearLayout>
<!-- Label container -->
<LinearLayout
style="@style/StatsSmallValueContainer"
android:layout_gravity="left|bottom">
<TextView
style="@style/StatsSmallValue"
android:visibility="invisible" />
<!-- Label -->
<TextView
android:id="@+id/stats_label"
style="@style/StatsSmallLabel"
android:layout_gravity="bottom"
android:paddingLeft="8dp" />
</LinearLayout>
</TableRow>
-33
View File
@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/StatsSmallItemContainer">
<!-- Label -->
<TextView
android:id="@+id/stats_label"
style="@style/StatsSmallLabel" />
<!-- Value container -->
<LinearLayout style="@style/StatsSmallValueContainer">
<!-- Value -->
<TextView
android:id="@+id/stats_value"
style="@style/StatsSmallValue" />
<!-- Unit -->
<TextView
android:id="@+id/stats_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
-33
View File
@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/StatsSmallItemContainer">
<!-- Label -->
<TextView
android:id="@+id/stats_label"
style="@style/StatsSmallLabel" />
<!-- Value container -->
<LinearLayout style="@style/StatsSmallValueContainer">
<!-- Value -->
<TextView
android:id="@+id/stats_value"
style="@style/StatsTinyValue" />
<!-- Unit -->
<TextView
android:id="@+id/stats_unit"
style="@style/StatsUnit" />
</LinearLayout>
</LinearLayout>
+3 -3
View File
@@ -172,7 +172,7 @@ limitations under the License.
</style>
<style name="StatsLargeValue">
<item name="android:layout_gravity">bottom</item>
<item name="android:layout_gravity">center</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:singleLine">true</item>
@@ -211,13 +211,13 @@ limitations under the License.
</style>
<!-- stats small value -->
<style name="StatsSmallValue" parent="@style/TextLarge">
<item name="android:layout_gravity">bottom</item>
<item name="android:layout_gravity">center</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">@android:color/white</item>
</style>
<!-- stats small value -->
<style name="StatsTinyValue" parent="@style/TextSmall">
<item name="android:layout_gravity">bottom</item>
<item name="android:layout_gravity">center</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">@android:color/white</item>
</style>