forked from upstream-mirrors/OpenTracks
Adaptive recording layout for sensors (heart rate, cycling cadence and cycling power).
This commit is contained in:
committed by
Dennis Guse
parent
634a7a4321
commit
d01715444f
@@ -0,0 +1,155 @@
|
|||||||
|
package de.dennisguse.opentracks.adapters;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Pair;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.R;
|
||||||
|
import de.dennisguse.opentracks.content.sensor.SensorData;
|
||||||
|
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
||||||
|
import de.dennisguse.opentracks.content.sensor.SensorDataCyclingPower;
|
||||||
|
import de.dennisguse.opentracks.content.sensor.SensorDataHeartRate;
|
||||||
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
|
||||||
|
public class SensorsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
|
||||||
|
public static final int HEART_RATE_TYPE = 0;
|
||||||
|
public static final int CADENCE_TYPE = 1;
|
||||||
|
public static final int POWER_TYPE = 2;
|
||||||
|
|
||||||
|
private List<Pair<Integer, SensorData>> sensorDataList;
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
|
public SensorsAdapter(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.sensor_item, parent, false);
|
||||||
|
return new SensorsAdapter.ViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||||
|
SensorsAdapter.ViewHolder viewHolder = (SensorsAdapter.ViewHolder) holder;
|
||||||
|
int type = sensorDataList.get(position).first;
|
||||||
|
SensorData sensorData = sensorDataList.get(position).second;
|
||||||
|
viewHolder.setData(sensorData, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
if (sensorDataList == null) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return sensorDataList.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return sensorDataList.get(position).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Pair<Integer, SensorData>> swapData(List<Pair<Integer, SensorData>> data) {
|
||||||
|
if (sensorDataList == data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
sensorDataList = data;
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
this.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView label;
|
||||||
|
TextView sensorValue;
|
||||||
|
TextView value;
|
||||||
|
TextView unit;
|
||||||
|
|
||||||
|
public ViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
label = itemView.findViewById(R.id.stats_sensor_label);
|
||||||
|
sensorValue = itemView.findViewById(R.id.stats_sensor_sensor_value);
|
||||||
|
value = itemView.findViewById(R.id.stats_sensor_value);
|
||||||
|
unit = itemView.findViewById(R.id.stats_sensor_unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(SensorData sensorData, int type) {
|
||||||
|
switch (type) {
|
||||||
|
case HEART_RATE_TYPE:
|
||||||
|
setHeartRateSensorData((SensorDataHeartRate) sensorData);
|
||||||
|
break;
|
||||||
|
case CADENCE_TYPE:
|
||||||
|
setCadenceSensorData((SensorDataCycling.Cadence) sensorData);
|
||||||
|
break;
|
||||||
|
case POWER_TYPE:
|
||||||
|
setPowerSensorData((SensorDataCyclingPower) sensorData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unknown sensor type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setHeartRateSensorData(SensorDataHeartRate data) {
|
||||||
|
String sensorValue = context.getString(R.string.value_unknown);
|
||||||
|
String sensorName = context.getString(R.string.value_unknown);
|
||||||
|
if (data != null) {
|
||||||
|
sensorName = data.getSensorNameOrAddress();
|
||||||
|
if (data.hasHeartRate_bpm() && data.isRecent()) {
|
||||||
|
sensorValue = StringUtils.formatDecimal(data.getHeartRate_bpm(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.label.setText(context.getString(R.string.sensor_state_heart_rate));
|
||||||
|
this.sensorValue.setText(sensorName);
|
||||||
|
this.value.setText(sensorValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCadenceSensorData(SensorDataCycling.Cadence data) {
|
||||||
|
String sensorValue = context.getString(R.string.value_unknown);
|
||||||
|
String sensorName = context.getString(R.string.value_unknown);
|
||||||
|
if (data != null) {
|
||||||
|
sensorName = data.getSensorNameOrAddress();
|
||||||
|
|
||||||
|
if (data.hasCadence_rpm() && data.isRecent()) {
|
||||||
|
sensorValue = StringUtils.formatDecimal(data.getCadence_rpm(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.label.setText(context.getString(R.string.sensor_state_cadence));
|
||||||
|
this.sensorValue.setText(sensorName);
|
||||||
|
this.value.setText(sensorValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPowerSensorData(SensorDataCyclingPower data) {
|
||||||
|
String sensorValue = context.getString(R.string.value_unknown);
|
||||||
|
String sensorName = context.getString(R.string.value_unknown);
|
||||||
|
if (data != null) {
|
||||||
|
sensorName = data.getSensorNameOrAddress();
|
||||||
|
|
||||||
|
if (data.hasPower_w() && data.isRecent()) {
|
||||||
|
sensorValue = StringUtils.formatDecimal(data.getPower_w(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.label.setText(context.getString(R.string.sensor_state_power));
|
||||||
|
this.sensorValue.setText(sensorName);
|
||||||
|
this.value.setText(sensorValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,17 +13,22 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.TrackRecordingActivity;
|
import de.dennisguse.opentracks.TrackRecordingActivity;
|
||||||
|
import de.dennisguse.opentracks.adapters.SensorsAdapter;
|
||||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||||
import de.dennisguse.opentracks.content.TrackDataListener;
|
import de.dennisguse.opentracks.content.TrackDataListener;
|
||||||
import de.dennisguse.opentracks.content.data.Marker;
|
import de.dennisguse.opentracks.content.data.Marker;
|
||||||
import de.dennisguse.opentracks.content.data.Track;
|
import de.dennisguse.opentracks.content.data.Track;
|
||||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
|
import de.dennisguse.opentracks.content.sensor.SensorData;
|
||||||
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
||||||
import de.dennisguse.opentracks.content.sensor.SensorDataCyclingPower;
|
|
||||||
import de.dennisguse.opentracks.content.sensor.SensorDataHeartRate;
|
|
||||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||||
import de.dennisguse.opentracks.databinding.StatisticsRecordingBinding;
|
import de.dennisguse.opentracks.databinding.StatisticsRecordingBinding;
|
||||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||||
@@ -61,6 +66,9 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
|
|||||||
|
|
||||||
private StatisticsRecordingBinding viewBinding;
|
private StatisticsRecordingBinding viewBinding;
|
||||||
|
|
||||||
|
private SensorsAdapter sensorsAdapter;
|
||||||
|
private RecyclerView sensorsRecyclerView;
|
||||||
|
|
||||||
public static Fragment newInstance() {
|
public static Fragment newInstance() {
|
||||||
return new StatisticsRecordingFragment();
|
return new StatisticsRecordingFragment();
|
||||||
}
|
}
|
||||||
@@ -115,6 +123,11 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sensorsAdapter = new SensorsAdapter(getContext());
|
||||||
|
sensorsRecyclerView = viewBinding.statsSensorsRecyclerView;
|
||||||
|
sensorsRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||||
|
sensorsRecyclerView.setAdapter(sensorsAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -272,78 +285,23 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
|
|||||||
} else {
|
} else {
|
||||||
SensorDataSet sensorDataSet = trackRecordingService.getSensorData();
|
SensorDataSet sensorDataSet = trackRecordingService.getSensorData();
|
||||||
if (sensorDataSet != null) {
|
if (sensorDataSet != null) {
|
||||||
setHeartRateSensorData(sensorDataSet);
|
List<Pair<Integer, SensorData>> sensorDataList = new ArrayList<>();
|
||||||
setCadenceSensorData(sensorDataSet);
|
if (sensorDataSet.getHeartRate() != null) {
|
||||||
setPowerSensorData(sensorDataSet);
|
sensorDataList.add(new Pair<>(SensorsAdapter.HEART_RATE_TYPE, sensorDataSet.getHeartRate()));
|
||||||
|
}
|
||||||
|
if (sensorDataSet.getCyclingCadence() != null) {
|
||||||
|
sensorDataList.add(new Pair<>(SensorsAdapter.CADENCE_TYPE, sensorDataSet.getCyclingCadence()));
|
||||||
|
}
|
||||||
|
if(sensorDataSet.getCyclingPower() != null) {
|
||||||
|
sensorDataList.add(new Pair<>(SensorsAdapter.POWER_TYPE, sensorDataSet.getCyclingPower()));
|
||||||
|
}
|
||||||
|
sensorsAdapter.swapData(sensorDataList);
|
||||||
setSpeedSensorData(sensorDataSet);
|
setSpeedSensorData(sensorDataSet);
|
||||||
}
|
}
|
||||||
setTotalElevationGain(trackRecordingService.getElevationGain_m());
|
setTotalElevationGain(trackRecordingService.getElevationGain_m());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setHeartRateSensorData(SensorDataSet sensorDataSet) {
|
|
||||||
int isVisible = sensorDataSet.getHeartRate() != null ? View.VISIBLE : View.GONE;
|
|
||||||
viewBinding.statsSensorHeartRateGroup.setVisibility(isVisible);
|
|
||||||
setVisibilitySensorHorizontalLine();
|
|
||||||
|
|
||||||
String sensorValue = getContext().getString(R.string.value_unknown);
|
|
||||||
String sensorName = getContext().getString(R.string.value_unknown);
|
|
||||||
if (sensorDataSet.getHeartRate() != null) {
|
|
||||||
SensorDataHeartRate data = sensorDataSet.getHeartRate();
|
|
||||||
|
|
||||||
sensorName = data.getSensorNameOrAddress();
|
|
||||||
if (data.hasHeartRate_bpm() && data.isRecent()) {
|
|
||||||
sensorValue = StringUtils.formatDecimal(data.getHeartRate_bpm(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewBinding.statsSensorHeartRateSensorValue.setText(sensorName);
|
|
||||||
viewBinding.statsSensorHeartRateValue.setText(sensorValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setCadenceSensorData(SensorDataSet sensorDataSet) {
|
|
||||||
int isVisible = sensorDataSet.getCyclingCadence() != null ? View.VISIBLE : View.GONE;
|
|
||||||
viewBinding.statsSensorCadenceGroup.setVisibility(isVisible);
|
|
||||||
setVisibilitySensorHorizontalLine();
|
|
||||||
|
|
||||||
String sensorValue = getContext().getString(R.string.value_unknown);
|
|
||||||
String sensorName = getContext().getString(R.string.value_unknown);
|
|
||||||
if (sensorDataSet.getCyclingCadence() != null) {
|
|
||||||
SensorDataCycling.Cadence data = sensorDataSet.getCyclingCadence();
|
|
||||||
sensorName = data.getSensorNameOrAddress();
|
|
||||||
|
|
||||||
if (data.hasCadence_rpm() && data.isRecent()) {
|
|
||||||
sensorValue = StringUtils.formatDecimal(data.getCadence_rpm(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewBinding.statsSensorCadenceSensorValue.setText(sensorName);
|
|
||||||
viewBinding.statsSensorCadenceValue.setText(sensorValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setPowerSensorData(SensorDataSet sensorDataSet) {
|
|
||||||
int isVisible = View.VISIBLE;
|
|
||||||
if (PreferencesUtils.isBluetoothCyclingPowerSensorAddressNone(getContext())) {
|
|
||||||
isVisible = View.GONE;
|
|
||||||
}
|
|
||||||
viewBinding.statsSensorPowerGroup.setVisibility(isVisible);
|
|
||||||
setVisibilitySensorHorizontalLine();
|
|
||||||
|
|
||||||
String sensorValue = getContext().getString(R.string.value_unknown);
|
|
||||||
String sensorName = getContext().getString(R.string.value_unknown);
|
|
||||||
if (sensorDataSet != null && sensorDataSet.getCyclingPower() != null) {
|
|
||||||
SensorDataCyclingPower data = sensorDataSet.getCyclingPower();
|
|
||||||
sensorName = data.getSensorName();
|
|
||||||
|
|
||||||
if (data.hasPower_w() && data.isRecent()) {
|
|
||||||
sensorValue = StringUtils.formatDecimal(data.getPower_w(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewBinding.statsSensorPowerSensorValue.setText(sensorName);
|
|
||||||
viewBinding.statsSensorPowerValue.setText(sensorValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set elevation gain
|
// Set elevation gain
|
||||||
private void setTotalElevationGain(Float elevationGain_m) {
|
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.
|
//TODO Check if we can distribute the total elevation gain via trackStatistics instead of doing some computation in the UI layer.
|
||||||
@@ -364,15 +322,6 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
|
|||||||
viewBinding.statsElevationGainUnit.setText(parts.second);
|
viewBinding.statsElevationGainUnit.setText(parts.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* If cadence and hear rate groups are invisible then sensor horizontal line hast to be invisible too.
|
|
||||||
*/
|
|
||||||
private void setVisibilitySensorHorizontalLine() {
|
|
||||||
if (viewBinding.statsSensorCadenceGroup.getVisibility() != View.VISIBLE && viewBinding.statsSensorHeartRateGroup.getVisibility() != View.VISIBLE) {
|
|
||||||
viewBinding.statsSensorHorizontalLine.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setSpeedSensorData(SensorDataSet sensorDataSet) {
|
private void setSpeedSensorData(SensorDataSet sensorDataSet) {
|
||||||
if (sensorDataSet != null && sensorDataSet.getCyclingSpeed() != null) {
|
if (sensorDataSet != null && sensorDataSet.getCyclingSpeed() != null) {
|
||||||
SensorDataCycling.Speed data = sensorDataSet.getCyclingSpeed();
|
SensorDataCycling.Speed data = sensorDataSet.getCyclingSpeed();
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stats_sensor_label"
|
||||||
|
style="@style/StatsLargeLabel"
|
||||||
|
tools:text="@string/sensor_state_heart_rate"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stats_sensor_sensor_value"
|
||||||
|
style="@style/StatsTinyValue"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/stats_sensor_label"
|
||||||
|
tools:text="90" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stats_sensor_value"
|
||||||
|
style="@style/StatsLargeValue"
|
||||||
|
android:value="@string/value_unknown"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/stats_sensor_sensor_value"
|
||||||
|
tools:text="90" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stats_sensor_unit"
|
||||||
|
style="@style/StatsUnit"
|
||||||
|
tools:text="@string/sensor_unit_beats_per_minute"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/stats_sensor_value" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -403,131 +403,14 @@
|
|||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_location_barrier" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_location_barrier" />
|
||||||
|
|
||||||
<!-- Heart rate -->
|
<!-- Sensors data -->
|
||||||
<androidx.constraintlayout.widget.Group
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/stats_sensor_heart_rate_group"
|
android:id="@+id/stats_sensors_recycler_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:constraint_referenced_ids="stats_sensor_heart_rate_label,stats_sensor_heart_rate_sensor_value,stats_sensor_heart_rate_value,stats_sensor_heart_rate_unit" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_heart_rate_label"
|
|
||||||
style="@style/StatsLargeLabel"
|
|
||||||
android:text="@string/sensor_state_heart_rate"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_sensor_horizontal_line" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_heart_rate_sensor_value"
|
|
||||||
style="@style/StatsTinyValue"
|
|
||||||
android:text="@string/value_unknown"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_heart_rate_label"
|
|
||||||
tools:text="90" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_heart_rate_value"
|
|
||||||
style="@style/StatsLargeValue"
|
|
||||||
android:value="@string/value_unknown"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_heart_rate_sensor_value"
|
|
||||||
tools:text="90" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_heart_rate_unit"
|
|
||||||
style="@style/StatsUnit"
|
|
||||||
android:text="@string/sensor_unit_beats_per_minute"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_heart_rate_value" />
|
|
||||||
|
|
||||||
<!-- Cadence -->
|
|
||||||
<androidx.constraintlayout.widget.Group
|
|
||||||
android:id="@+id/stats_sensor_cadence_group"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:constraint_referenced_ids="stats_sensor_cadence_label,stats_sensor_cadence_sensor_value,stats_sensor_cadence_value,stats_sensor_cadence_unit" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_cadence_label"
|
|
||||||
style="@style/StatsLargeLabel"
|
|
||||||
android:text="@string/sensor_state_cadence"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_sensor_horizontal_line" />
|
app:layout_constraintTop_toBottomOf="@id/stats_sensor_horizontal_line" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_cadence_sensor_value"
|
|
||||||
style="@style/StatsTinyValue"
|
|
||||||
android:text="@string/value_unknown"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_cadence_label"
|
|
||||||
tools:text="90" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_cadence_value"
|
|
||||||
style="@style/StatsLargeValue"
|
|
||||||
android:value="@string/value_unknown"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_cadence_sensor_value"
|
|
||||||
tools:text="90" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_cadence_unit"
|
|
||||||
style="@style/StatsUnit"
|
|
||||||
android:text="@string/sensor_unit_rounds_per_minute"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_cadence_value" />
|
|
||||||
|
|
||||||
<!-- Cycling Power -->
|
|
||||||
<androidx.constraintlayout.widget.Group
|
|
||||||
android:id="@+id/stats_sensor_power_group"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:constraint_referenced_ids="stats_sensor_power_label,stats_sensor_power_sensor_value,stats_sensor_power_value,stats_sensor_power_unit" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_power_label"
|
|
||||||
style="@style/StatsLargeLabel"
|
|
||||||
android:text="@string/sensor_state_power"
|
|
||||||
app:layout_constrainedWidth="true"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_sensor_horizontal_line" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_power_sensor_value"
|
|
||||||
style="@style/StatsTinyValue"
|
|
||||||
android:text="@string/value_unknown"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_power_label"
|
|
||||||
tools:text="90" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_power_value"
|
|
||||||
style="@style/StatsLargeValue"
|
|
||||||
android:value="@string/value_unknown"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_power_sensor_value"
|
|
||||||
tools:text="90" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/stats_sensor_power_unit"
|
|
||||||
style="@style/StatsUnit"
|
|
||||||
android:text="@string/sensor_unit_power"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_power_value" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
Reference in New Issue
Block a user