mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-28 04:46:51 +01:00
Add heart rate average to Activity and Sleep → Sleep
This commit is contained in:
parent
e8534e01f8
commit
329c47fff2
@ -146,6 +146,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
protected int AK_NOT_WORN_COLOR;
|
protected int AK_NOT_WORN_COLOR;
|
||||||
|
|
||||||
protected String HEARTRATE_LABEL;
|
protected String HEARTRATE_LABEL;
|
||||||
|
protected String HEARTRATE_AVERAGE_LABEL;
|
||||||
|
|
||||||
protected AbstractChartFragment(String... intentFilterActions) {
|
protected AbstractChartFragment(String... intentFilterActions) {
|
||||||
mIntentFilterActions = new HashSet<>();
|
mIntentFilterActions = new HashSet<>();
|
||||||
@ -197,6 +198,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
AK_NOT_WORN_COLOR = runningColor.data;
|
AK_NOT_WORN_COLOR = runningColor.data;
|
||||||
|
|
||||||
HEARTRATE_LABEL = getContext().getString(R.string.charts_legend_heartrate);
|
HEARTRATE_LABEL = getContext().getString(R.string.charts_legend_heartrate);
|
||||||
|
HEARTRATE_AVERAGE_LABEL = getContext().getString(R.string.charts_legend_heartrate_average);
|
||||||
|
|
||||||
akActivity = new ActivityConfig(ActivityKind.TYPE_ACTIVITY, getString(R.string.abstract_chart_fragment_kind_activity), AK_ACTIVITY_COLOR);
|
akActivity = new ActivityConfig(ActivityKind.TYPE_ACTIVITY, getString(R.string.abstract_chart_fragment_kind_activity), AK_ACTIVITY_COLOR);
|
||||||
akLightSleep = new ActivityConfig(ActivityKind.TYPE_LIGHT_SLEEP, getString(R.string.abstract_chart_fragment_kind_light_sleep), AK_LIGHT_SLEEP_COLOR);
|
akLightSleep = new ActivityConfig(ActivityKind.TYPE_LIGHT_SLEEP, getString(R.string.abstract_chart_fragment_kind_light_sleep), AK_LIGHT_SLEEP_COLOR);
|
||||||
|
@ -19,10 +19,13 @@ package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Pair;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.github.mikephil.charting.animation.Easing;
|
import com.github.mikephil.charting.animation.Easing;
|
||||||
@ -30,6 +33,7 @@ import com.github.mikephil.charting.charts.Chart;
|
|||||||
import com.github.mikephil.charting.charts.LineChart;
|
import com.github.mikephil.charting.charts.LineChart;
|
||||||
import com.github.mikephil.charting.charts.PieChart;
|
import com.github.mikephil.charting.charts.PieChart;
|
||||||
import com.github.mikephil.charting.components.LegendEntry;
|
import com.github.mikephil.charting.components.LegendEntry;
|
||||||
|
import com.github.mikephil.charting.components.LimitLine;
|
||||||
import com.github.mikephil.charting.components.XAxis;
|
import com.github.mikephil.charting.components.XAxis;
|
||||||
import com.github.mikephil.charting.components.YAxis;
|
import com.github.mikephil.charting.components.YAxis;
|
||||||
import com.github.mikephil.charting.data.LineData;
|
import com.github.mikephil.charting.data.LineData;
|
||||||
@ -38,9 +42,11 @@ import com.github.mikephil.charting.data.PieDataSet;
|
|||||||
import com.github.mikephil.charting.data.PieEntry;
|
import com.github.mikephil.charting.data.PieEntry;
|
||||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Triple;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -66,17 +72,22 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
private LineChart mActivityChart;
|
private LineChart mActivityChart;
|
||||||
private PieChart mSleepAmountChart;
|
private PieChart mSleepAmountChart;
|
||||||
private TextView mSleepchartInfo;
|
private TextView mSleepchartInfo;
|
||||||
|
private TextView heartRateAverageLabel;
|
||||||
|
private ImageView heartRateWidget;
|
||||||
|
|
||||||
private int mSmartAlarmFrom = -1;
|
private int mSmartAlarmFrom = -1;
|
||||||
private int mSmartAlarmTo = -1;
|
private int mSmartAlarmTo = -1;
|
||||||
private int mTimestampFrom = -1;
|
private int mTimestampFrom = -1;
|
||||||
private int mSmartAlarmGoneOff = -1;
|
private int mSmartAlarmGoneOff = -1;
|
||||||
|
Prefs prefs = GBApplication.getPrefs();
|
||||||
|
private boolean CHARTS_SLEEP_RANGE_24H = prefs.getBoolean("chart_sleep_range_24h", false);
|
||||||
|
private boolean SHOW_CHARTS_AVERAGE = GBApplication.getPrefs().getBoolean("charts_show_average", true);
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ChartsData refreshInBackground(ChartsHost chartsHost, DBHandler db, GBDevice device) {
|
protected ChartsData refreshInBackground(ChartsHost chartsHost, DBHandler db, GBDevice device) {
|
||||||
Prefs prefs = GBApplication.getPrefs();
|
|
||||||
List<? extends ActivitySample> samples;
|
List<? extends ActivitySample> samples;
|
||||||
if (prefs.getBoolean("chart_sleep_range_24h", false)) {
|
if (CHARTS_SLEEP_RANGE_24H) {
|
||||||
samples = getSamples(db, device);
|
samples = getSamples(db, device);
|
||||||
} else {
|
} else {
|
||||||
samples = getSamplesofSleep(db, device);
|
samples = getSamplesofSleep(db, device);
|
||||||
@ -84,7 +95,7 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
|
|
||||||
MySleepChartsData mySleepChartsData = refreshSleepAmounts(device, samples);
|
MySleepChartsData mySleepChartsData = refreshSleepAmounts(device, samples);
|
||||||
|
|
||||||
if (!prefs.getBoolean("chart_sleep_range_24h", false)) {
|
if (!CHARTS_SLEEP_RANGE_24H) {
|
||||||
if (mySleepChartsData.sleepSessions.size() > 0) {
|
if (mySleepChartsData.sleepSessions.size() > 0) {
|
||||||
long tstart = mySleepChartsData.sleepSessions.get(0).getSleepStart().getTime() / 1000;
|
long tstart = mySleepChartsData.sleepSessions.get(0).getSleepStart().getTime() / 1000;
|
||||||
long tend = mySleepChartsData.sleepSessions.get(mySleepChartsData.sleepSessions.size() - 1).getSleepEnd().getTime() / 1000;
|
long tend = mySleepChartsData.sleepSessions.get(mySleepChartsData.sleepSessions.size() - 1).getSleepEnd().getTime() / 1000;
|
||||||
@ -98,10 +109,14 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultChartsData chartsData = refresh(device, samples);
|
DefaultChartsData chartsData = refresh(device, samples);
|
||||||
|
Triple<Float, Integer, Integer> hrData = calculateHrData(samples);
|
||||||
return new MyChartsData(mySleepChartsData, chartsData);
|
//Pair<Float, Float> intensityMinMax = calculateIntensityMinMax(samples); //so far unused
|
||||||
|
Pair<Float, Float> intensityMinMax = Pair.create(0f, 0f);
|
||||||
|
return new MyChartsData(mySleepChartsData, chartsData, hrData.getLeft(), hrData.getMiddle(), hrData.getRight(), intensityMinMax.first, intensityMinMax.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private MySleepChartsData refreshSleepAmounts(GBDevice mGBDevice, List<? extends ActivitySample> samples) {
|
private MySleepChartsData refreshSleepAmounts(GBDevice mGBDevice, List<? extends ActivitySample> samples) {
|
||||||
SleepAnalysis sleepAnalysis = new SleepAnalysis();
|
SleepAnalysis sleepAnalysis = new SleepAnalysis();
|
||||||
List<SleepSession> sleepSessions = sleepAnalysis.calculateSleepSessions(samples);
|
List<SleepSession> sleepSessions = sleepAnalysis.calculateSleepSessions(samples);
|
||||||
@ -173,13 +188,76 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
MySleepChartsData pieData = mcd.getPieData();
|
MySleepChartsData pieData = mcd.getPieData();
|
||||||
mSleepAmountChart.setCenterText(pieData.getTotalSleep());
|
mSleepAmountChart.setCenterText(pieData.getTotalSleep());
|
||||||
mSleepAmountChart.setData(pieData.getPieData());
|
mSleepAmountChart.setData(pieData.getPieData());
|
||||||
|
|
||||||
mActivityChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
|
mActivityChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
|
||||||
mActivityChart.getXAxis().setValueFormatter(mcd.getChartsData().getXValueFormatter());
|
mActivityChart.getXAxis().setValueFormatter(mcd.getChartsData().getXValueFormatter());
|
||||||
mActivityChart.setData(mcd.getChartsData().getData());
|
mActivityChart.setData(mcd.getChartsData().getData());
|
||||||
|
|
||||||
|
|
||||||
mSleepchartInfo.setText(buildYouSleptText(pieData));
|
mSleepchartInfo.setText(buildYouSleptText(pieData));
|
||||||
|
|
||||||
|
if (!CHARTS_SLEEP_RANGE_24H
|
||||||
|
&& supportsHeartrate(getChartsHost().getDevice())
|
||||||
|
&& SHOW_CHARTS_AVERAGE) {
|
||||||
|
if (mcd.getHeartRateAxisMax() != 0 || mcd.getHeartRateAxisMin() != 0) {
|
||||||
|
mActivityChart.getAxisRight().setAxisMaximum(mcd.getHeartRateAxisMax());
|
||||||
|
mActivityChart.getAxisRight().setAxisMinimum(mcd.getHeartRateAxisMin());
|
||||||
|
}
|
||||||
|
LimitLine hrAverage_line = new LimitLine(mcd.getHeartRateAverage());
|
||||||
|
hrAverage_line.setLineColor(Color.RED);
|
||||||
|
hrAverage_line.setLineWidth(0.1f);
|
||||||
|
mActivityChart.getAxisRight().removeAllLimitLines();
|
||||||
|
mActivityChart.getAxisRight().addLimitLine(hrAverage_line);
|
||||||
|
DecimalFormat df = new DecimalFormat("##.#");
|
||||||
|
heartRateAverageLabel.setText(df.format(mcd.getHeartRateAverage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Triple<Float, Integer, Integer> calculateHrData(List<? extends ActivitySample> samples) {
|
||||||
|
if (samples.toArray().length < 1) {
|
||||||
|
return Triple.of(0f, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> heartRateValues = new ArrayList<>();
|
||||||
|
HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance();
|
||||||
|
for (ActivitySample sample : samples) {
|
||||||
|
if (sample.getKind() == ActivityKind.TYPE_LIGHT_SLEEP || sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
||||||
|
int heartRate = sample.getHeartRate();
|
||||||
|
if (heartRateUtilsInstance.isValidHeartRateValue(heartRate)) {
|
||||||
|
heartRateValues.add(heartRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (heartRateValues.toArray().length < 1) {
|
||||||
|
return Triple.of(0f, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int min = Collections.min(heartRateValues);
|
||||||
|
int max = Collections.max(heartRateValues);
|
||||||
|
int count = heartRateValues.toArray().length;
|
||||||
|
float sum = calculateSum(heartRateValues);
|
||||||
|
float average = sum / count;
|
||||||
|
return Triple.of(average, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float calculateSum(List<Integer> samples) {
|
||||||
|
float result = 0;
|
||||||
|
for (Integer sample : samples) {
|
||||||
|
result += sample;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<Float, Float> calculateIntensityMinMax(List<? extends ActivitySample> samples) {
|
||||||
|
List<Float> allIntensities = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ActivitySample s : samples) {
|
||||||
|
if (s.getKind() == ActivityKind.TYPE_LIGHT_SLEEP || s.getKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
||||||
|
float HR = s.getIntensity();
|
||||||
|
allIntensities.add(HR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Float min = Collections.min(allIntensities);
|
||||||
|
Float max = Collections.max(allIntensities);
|
||||||
|
return Pair.create(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildYouSleptText(MySleepChartsData pieData) {
|
private String buildYouSleptText(MySleepChartsData pieData) {
|
||||||
@ -211,6 +289,8 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
mActivityChart = rootView.findViewById(R.id.sleepchart);
|
mActivityChart = rootView.findViewById(R.id.sleepchart);
|
||||||
mSleepAmountChart = rootView.findViewById(R.id.sleepchart_pie_light_deep);
|
mSleepAmountChart = rootView.findViewById(R.id.sleepchart_pie_light_deep);
|
||||||
mSleepchartInfo = rootView.findViewById(R.id.sleepchart_info);
|
mSleepchartInfo = rootView.findViewById(R.id.sleepchart_info);
|
||||||
|
heartRateWidget = rootView.findViewById(R.id.heartrate_widget_icon);
|
||||||
|
heartRateAverageLabel = rootView.findViewById(R.id.heartrate_widget_label);
|
||||||
|
|
||||||
setupActivityChart();
|
setupActivityChart();
|
||||||
setupSleepAmountChart();
|
setupSleepAmountChart();
|
||||||
@ -276,8 +356,8 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
yAxisRight.setDrawLabels(true);
|
yAxisRight.setDrawLabels(true);
|
||||||
yAxisRight.setDrawTopYLabelEntry(true);
|
yAxisRight.setDrawTopYLabelEntry(true);
|
||||||
yAxisRight.setTextColor(CHART_TEXT_COLOR);
|
yAxisRight.setTextColor(CHART_TEXT_COLOR);
|
||||||
yAxisRight.setAxisMaxValue(HeartRateUtils.getInstance().getMaxHeartRate());
|
yAxisRight.setAxisMaximum(HeartRateUtils.getInstance().getMaxHeartRate());
|
||||||
yAxisRight.setAxisMinValue(HeartRateUtils.getInstance().getMinHeartRate());
|
yAxisRight.setAxisMinimum(HeartRateUtils.getInstance().getMinHeartRate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -292,12 +372,20 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
deepSleepEntry.label = akDeepSleep.label;
|
deepSleepEntry.label = akDeepSleep.label;
|
||||||
deepSleepEntry.formColor = akDeepSleep.color;
|
deepSleepEntry.formColor = akDeepSleep.color;
|
||||||
legendEntries.add(deepSleepEntry);
|
legendEntries.add(deepSleepEntry);
|
||||||
|
heartRateWidget.setVisibility(View.GONE); //hide heart icon
|
||||||
|
|
||||||
if (supportsHeartrate(getChartsHost().getDevice())) {
|
if (supportsHeartrate(getChartsHost().getDevice())) {
|
||||||
LegendEntry hrEntry = new LegendEntry();
|
LegendEntry hrEntry = new LegendEntry();
|
||||||
hrEntry.label = HEARTRATE_LABEL;
|
hrEntry.label = HEARTRATE_LABEL;
|
||||||
hrEntry.formColor = HEARTRATE_COLOR;
|
hrEntry.formColor = HEARTRATE_COLOR;
|
||||||
legendEntries.add(hrEntry);
|
legendEntries.add(hrEntry);
|
||||||
|
if (!CHARTS_SLEEP_RANGE_24H && SHOW_CHARTS_AVERAGE) {
|
||||||
|
LegendEntry hrAverageEntry = new LegendEntry();
|
||||||
|
hrAverageEntry.label = HEARTRATE_AVERAGE_LABEL;
|
||||||
|
hrAverageEntry.formColor = Color.RED;
|
||||||
|
legendEntries.add(hrAverageEntry);
|
||||||
|
heartRateWidget.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chart.getLegend().setCustom(legendEntries);
|
chart.getLegend().setCustom(legendEntries);
|
||||||
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
|
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
|
||||||
@ -343,10 +431,18 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
private static class MyChartsData extends ChartsData {
|
private static class MyChartsData extends ChartsData {
|
||||||
private final DefaultChartsData<LineData> chartsData;
|
private final DefaultChartsData<LineData> chartsData;
|
||||||
private final MySleepChartsData pieData;
|
private final MySleepChartsData pieData;
|
||||||
|
private final float heartRateAverage;
|
||||||
|
private float heartRateAxisMax;
|
||||||
|
private float heartRateAxisMin;
|
||||||
|
private float intensityAxisMax;
|
||||||
|
private float intensityAxisMin;
|
||||||
|
|
||||||
public MyChartsData(MySleepChartsData pieData, DefaultChartsData<LineData> chartsData) {
|
public MyChartsData(MySleepChartsData pieData, DefaultChartsData<LineData> chartsData, float heartRateAverage, float heartRateAxisMin, float heartRateAxisMax, float intensityAxisMin, float intensityAxisMax) {
|
||||||
this.pieData = pieData;
|
this.pieData = pieData;
|
||||||
this.chartsData = chartsData;
|
this.chartsData = chartsData;
|
||||||
|
this.heartRateAverage = heartRateAverage;
|
||||||
|
this.heartRateAxisMax = heartRateAxisMax;
|
||||||
|
this.heartRateAxisMin = heartRateAxisMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySleepChartsData getPieData() {
|
public MySleepChartsData getPieData() {
|
||||||
@ -356,5 +452,25 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
public DefaultChartsData<LineData> getChartsData() {
|
public DefaultChartsData<LineData> getChartsData() {
|
||||||
return chartsData;
|
return chartsData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getHeartRateAverage() {
|
||||||
|
return heartRateAverage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHeartRateAxisMax() {
|
||||||
|
return heartRateAxisMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHeartRateAxisMin() {
|
||||||
|
return heartRateAxisMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getIntensityAxisMax() {
|
||||||
|
return intensityAxisMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getIntensityAxisMin() {
|
||||||
|
return intensityAxisMin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,6 +24,7 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||||
@ -64,12 +65,12 @@ public class StepAnalysis {
|
|||||||
|
|
||||||
float activeIntensity = 0;
|
float activeIntensity = 0;
|
||||||
float intensityBetweenActivePeriods = 0;
|
float intensityBetweenActivePeriods = 0;
|
||||||
|
HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance();
|
||||||
|
|
||||||
for (ActivitySample sample : samples) {
|
for (ActivitySample sample : samples) {
|
||||||
if (sample.getKind() != ActivityKind.TYPE_SLEEP //anything but sleep counts
|
if (sample.getKind() != ActivityKind.TYPE_SLEEP //anything but sleep counts
|
||||||
&& !(sample instanceof TrailingActivitySample)) { //trailing samples have wrong date and make trailing activity have 0 duration
|
&& !(sample instanceof TrailingActivitySample)) { //trailing samples have wrong date and make trailing activity have 0 duration
|
||||||
if (sample.getHeartRate() != 255 && sample.getHeartRate() != -1) {
|
if (heartRateUtilsInstance.isValidHeartRateValue(sample.getHeartRate())) {
|
||||||
heartRateToAdd = sample.getHeartRate();
|
heartRateToAdd = sample.getHeartRate();
|
||||||
activeHrSamplesToAdd = 1;
|
activeHrSamplesToAdd = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,8 +1,23 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment"
|
android:orientation="vertical"
|
||||||
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment">
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/heartrate_average_widget"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_gravity="top|end"
|
||||||
|
android:layout_marginTop="-5dp"
|
||||||
|
android:layout_marginEnd="-2dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -38,3 +53,4 @@
|
|||||||
<!--android:layout_weight="20" />-->
|
<!--android:layout_weight="20" />-->
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment"
|
android:orientation="vertical"
|
||||||
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment">
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/heartrate_average_widget"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_gravity="top|end" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -24,3 +37,5 @@
|
|||||||
android:layout_weight="2" />
|
android:layout_weight="2" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
31
app/src/main/res/layout/heartrate_average_widget.xml
Normal file
31
app/src/main/res/layout/heartrate_average_widget.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/heartrate_widget_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/heartrate_widget_icon"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:contentDescription="@string/heart_rate"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_heart" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/heartrate_widget_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="6dp"
|
||||||
|
android:text=""
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -633,6 +633,7 @@
|
|||||||
<string name="updatefirmwareoperation_firmware_not_sent">Firmware not sent</string>
|
<string name="updatefirmwareoperation_firmware_not_sent">Firmware not sent</string>
|
||||||
<string name="charts_legend_heartrate">Heart rate</string>
|
<string name="charts_legend_heartrate">Heart rate</string>
|
||||||
<string name="live_activity_heart_rate">Heart rate</string>
|
<string name="live_activity_heart_rate">Heart rate</string>
|
||||||
|
<string name="charts_legend_heartrate_average">Heart rate average</string>
|
||||||
<string name="activity_prefs_calories_burnt">Daily target: calories burnt</string>
|
<string name="activity_prefs_calories_burnt">Daily target: calories burnt</string>
|
||||||
<string name="activity_prefs_distance_meters">Daily target: distance in meters</string>
|
<string name="activity_prefs_distance_meters">Daily target: distance in meters</string>
|
||||||
<string name="activity_prefs_activetime_minutes">Daily target: active time in minutes</string>
|
<string name="activity_prefs_activetime_minutes">Daily target: active time in minutes</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user