mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-09 03:37:03 +01:00
Sleep tabs refactor
This commit is contained in:
parent
2f21c4bd9d
commit
a3e6d446d7
@ -65,12 +65,12 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
protected final int TOTAL_DAYS = getRangeDays();
|
||||
protected int TOTAL_DAYS_FOR_AVERAGE = 0;
|
||||
|
||||
private Locale mLocale;
|
||||
private int mTargetValue = 0;
|
||||
protected Locale mLocale;
|
||||
protected int mTargetValue = 0;
|
||||
|
||||
private PieChart mTodayPieChart;
|
||||
private BarChart mWeekChart;
|
||||
private TextView mBalanceView;
|
||||
protected PieChart mTodayPieChart;
|
||||
protected BarChart mWeekChart;
|
||||
protected TextView mBalanceView;
|
||||
|
||||
private int mOffsetHours = getOffsetHours();
|
||||
ImageView stepsStreaksButton;
|
||||
@ -113,7 +113,7 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
}
|
||||
}
|
||||
|
||||
private boolean enableStepStreaksButton(){
|
||||
protected boolean enableStepStreaksButton(){
|
||||
return this.getClass().getSimpleName().equals("WeekStepsChartFragment");
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
// mBalanceView.setText(getBalanceMessage(balance));
|
||||
}
|
||||
|
||||
private String getWeeksChartsLabel(Calendar day){
|
||||
protected String getWeeksChartsLabel(Calendar day){
|
||||
if (GBApplication.getPrefs().getBoolean("charts_range", true)) {
|
||||
//month, show day date
|
||||
return String.valueOf(day.get(Calendar.DAY_OF_MONTH));
|
||||
@ -134,10 +134,9 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
return day.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, mLocale);
|
||||
}
|
||||
}
|
||||
|
||||
private WeekChartsData<BarData> refreshWeekBeforeData(DBHandler db, BarChart barChart, Calendar day, GBDevice device) {
|
||||
protected WeekChartsData<BarData> refreshWeekBeforeData(DBHandler db, BarChart barChart, Calendar day, GBDevice device) {
|
||||
day = (Calendar) day.clone(); // do not modify the caller's argument
|
||||
day.add(Calendar.DATE, -TOTAL_DAYS);
|
||||
day.add(Calendar.DATE, -TOTAL_DAYS + 1);
|
||||
List<BarEntry> entries = new ArrayList<>();
|
||||
ArrayList<String> labels = new ArrayList<String>();
|
||||
|
||||
@ -191,10 +190,10 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
}
|
||||
}
|
||||
|
||||
return new WeekChartsData(barData, new PreformattedXIndexLabelFormatter(labels), getBalanceMessage(balance, mTargetValue));
|
||||
return new WeekChartsData(barData, new PreformattedXIndexLabelFormatter(labels), getBalanceMessage(balance, mTargetValue));
|
||||
}
|
||||
|
||||
private DayData refreshDayPie(DBHandler db, Calendar day, GBDevice device) {
|
||||
protected DayData refreshDayPie(DBHandler db, Calendar day, GBDevice device) {
|
||||
|
||||
PieData data = new PieData();
|
||||
List<PieEntry> entries = new ArrayList<>();
|
||||
@ -276,7 +275,7 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
|
||||
|
||||
|
||||
private void setupTodayPieChart() {
|
||||
protected void setupTodayPieChart() {
|
||||
mTodayPieChart.setBackgroundColor(BACKGROUND_COLOR);
|
||||
mTodayPieChart.getDescription().setTextColor(DESCRIPTION_COLOR);
|
||||
mTodayPieChart.setEntryLabelColor(DESCRIPTION_COLOR);
|
||||
@ -286,7 +285,7 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
mTodayPieChart.getLegend().setEnabled(false);
|
||||
}
|
||||
|
||||
private void setupWeekChart() {
|
||||
protected void setupWeekChart() {
|
||||
mWeekChart.setBackgroundColor(BACKGROUND_COLOR);
|
||||
mWeekChart.getDescription().setTextColor(DESCRIPTION_COLOR);
|
||||
mWeekChart.getDescription().setText("");
|
||||
@ -369,7 +368,7 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
}
|
||||
}
|
||||
|
||||
private ActivityAmounts getActivityAmountsForDay(DBHandler db, Calendar day, GBDevice device) {
|
||||
protected ActivityAmounts getActivityAmountsForDay(DBHandler db, Calendar day, GBDevice device) {
|
||||
|
||||
LimitedQueue<Integer, ActivityAmounts> activityAmountCache = null;
|
||||
ActivityAmounts amounts = null;
|
||||
@ -426,7 +425,7 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
|
||||
protected abstract String getBalanceMessage(long balance, int targetValue);
|
||||
|
||||
private class WeekChartsData<T extends ChartData<?>> extends DefaultChartsData<T> {
|
||||
protected class WeekChartsData<T extends ChartData<?>> extends DefaultChartsData<T> {
|
||||
private final String balanceMessage;
|
||||
|
||||
public WeekChartsData(T data, PreformattedXIndexLabelFormatter xIndexLabelFormatter, String balanceMessage) {
|
||||
|
@ -20,12 +20,14 @@ package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
@ -34,10 +36,7 @@ import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
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.YAxis;
|
||||
import com.github.mikephil.charting.components.*;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
@ -49,10 +48,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
@ -73,10 +70,14 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
private LineChart mActivityChart;
|
||||
private PieChart mSleepAmountChart;
|
||||
private TextView mSleepchartInfo;
|
||||
private TextView heartRateAverageLabel;
|
||||
private ImageView heartRateIcon;
|
||||
private TextView intensityTotalLabel;
|
||||
private ImageView intensityTotalIcon;
|
||||
private TextView remSleepTimeText;
|
||||
private LinearLayout remSleepTimeTextWrapper;
|
||||
private TextView deepSleepTimeText;
|
||||
private TextView lightSleepTimeText;
|
||||
private TextView lowestHrText;
|
||||
private TextView highestHrText;
|
||||
private TextView movementIntensityText;
|
||||
private TextView sleepDateText;
|
||||
private int heartRateMin = 0;
|
||||
private int heartRateMax = 0;
|
||||
private float intensityTotal = 0;
|
||||
@ -135,7 +136,6 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
final long lightSleepDuration = calculateLightSleepDuration(sleepSessions);
|
||||
final long deepSleepDuration = calculateDeepSleepDuration(sleepSessions);
|
||||
final long remSleepDuration = calculateRemSleepDuration(sleepSessions);
|
||||
|
||||
final long totalSeconds = lightSleepDuration + deepSleepDuration + remSleepDuration;
|
||||
|
||||
final List<PieEntry> entries = new ArrayList<>();
|
||||
@ -151,16 +151,14 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
entries.add(new PieEntry(remSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_rem_sleep)));
|
||||
colors.add(getColorFor(ActivityKind.TYPE_REM_SLEEP));
|
||||
}
|
||||
|
||||
} else {
|
||||
entries.add(new PieEntry(1));
|
||||
colors.add(Color.GRAY);
|
||||
}
|
||||
|
||||
String totalSleep = DateTimeUtils.formatDurationHoursMinutes(totalSeconds, TimeUnit.SECONDS);
|
||||
PieDataSet set = new PieDataSet(entries, "");
|
||||
set.setValueFormatter(new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return DateTimeUtils.formatDurationHoursMinutes((long) value, TimeUnit.SECONDS);
|
||||
}
|
||||
});
|
||||
set.setSliceSpace(2f);
|
||||
set.setColors(colors);
|
||||
set.setValueTextColor(DESCRIPTION_COLOR);
|
||||
set.setValueTextSize(13f);
|
||||
@ -168,8 +166,12 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
set.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||
data.setDataSet(set);
|
||||
|
||||
String totalSleep = DateTimeUtils.formatDurationHoursMinutes(totalSeconds, TimeUnit.SECONDS);
|
||||
String totalRem = DateTimeUtils.formatDurationHoursMinutes(remSleepDuration, TimeUnit.SECONDS);
|
||||
String totalDeep = DateTimeUtils.formatDurationHoursMinutes(deepSleepDuration, TimeUnit.SECONDS);
|
||||
String totalLight = DateTimeUtils.formatDurationHoursMinutes(lightSleepDuration, TimeUnit.SECONDS);
|
||||
//setupLegend(pieChart);
|
||||
return new MySleepChartsData(totalSleep, data, sleepSessions);
|
||||
return new MySleepChartsData(data, sleepSessions, totalSleep, totalRem, totalDeep, totalLight);
|
||||
}
|
||||
|
||||
private long calculateLightSleepDuration(List<SleepSession> sleepSessions) {
|
||||
@ -199,16 +201,47 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
@Override
|
||||
protected void updateChartsnUIThread(MyChartsData mcd) {
|
||||
MySleepChartsData pieData = mcd.getPieData();
|
||||
|
||||
Date date = new Date((long) this.getTSEnd() * 1000);
|
||||
String formattedDate = new SimpleDateFormat("E, MMM dd").format(date);
|
||||
sleepDateText.setText(formattedDate);
|
||||
|
||||
pieData.pieData.setDrawValues(false);
|
||||
mSleepAmountChart.setTouchEnabled(false);
|
||||
mSleepAmountChart.setCenterTextColor(GBApplication.getTextColor(getContext()));
|
||||
mSleepAmountChart.setCenterText(pieData.getTotalSleep());
|
||||
if (!pieData.sleepSessions.isEmpty()) {
|
||||
remSleepTimeText.setText(pieData.getTotalRem());
|
||||
deepSleepTimeText.setText(pieData.getTotalDeep());
|
||||
lightSleepTimeText.setText(pieData.getTotalLight());
|
||||
} else {
|
||||
remSleepTimeText.setText("-");
|
||||
deepSleepTimeText.setText("-");
|
||||
lightSleepTimeText.setText("-");
|
||||
}
|
||||
if (!supportsRemSleep(getChartsHost().getDevice())) {
|
||||
remSleepTimeTextWrapper.setVisibility(View.GONE);
|
||||
}
|
||||
mSleepAmountChart.setCenterTextSize(18f);
|
||||
mSleepAmountChart.setHoleColor(getContext().getResources().getColor(R.color.transparent));
|
||||
mSleepAmountChart.setData(pieData.getPieData());
|
||||
mActivityChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
|
||||
mActivityChart.getXAxis().setValueFormatter(mcd.getChartsData().getXValueFormatter());
|
||||
mActivityChart.setData(mcd.getChartsData().getData());
|
||||
mSleepchartInfo.setText(buildYouSleptText(pieData));
|
||||
mSleepchartInfo.setMovementMethod(new ScrollingMovementMethod());
|
||||
mActivityChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
|
||||
mActivityChart.getXAxis().setValueFormatter(mcd.getChartsData().getXValueFormatter());
|
||||
mActivityChart.getAxisLeft().setDrawLabels(false);
|
||||
|
||||
mActivityChart.setData(mcd.getChartsData().getData());
|
||||
heartRateMin = mcd.getHeartRateAxisMin();
|
||||
heartRateMax = mcd.getHeartRateAxisMax();
|
||||
intensityTotal = mcd.getIntensityTotal();
|
||||
lowestHrText.setText(String.valueOf(heartRateMin != 0 ? heartRateMin : "-"));
|
||||
highestHrText.setText(String.valueOf(heartRateMax != 0 ? heartRateMax : "-"));
|
||||
movementIntensityText.setText(intensityTotal != 0 ? new DecimalFormat("###.#").format(intensityTotal) : "-");
|
||||
|
||||
mSleepAmountChart.setHoleRadius(75);
|
||||
mSleepAmountChart.setDrawEntryLabels(false);
|
||||
mSleepAmountChart.getLegend().setEnabled(false);
|
||||
|
||||
if (!CHARTS_SLEEP_RANGE_24H
|
||||
&& supportsHeartrate(getChartsHost().getDevice())
|
||||
@ -222,9 +255,6 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
hrAverage_line.setLineWidth(0.1f);
|
||||
mActivityChart.getAxisRight().removeAllLimitLines();
|
||||
mActivityChart.getAxisRight().addLimitLine(hrAverage_line);
|
||||
DecimalFormat df = new DecimalFormat("###.#");
|
||||
heartRateAverageLabel.setText(df.format(mcd.getHeartRateAverage()));
|
||||
intensityTotalLabel.setText(df.format(mcd.getIntensityTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,17 +327,14 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
|
||||
private String buildYouSleptText(MySleepChartsData pieData) {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
if (pieData.getSleepSessions().isEmpty()) {
|
||||
result.append(getContext().getString(R.string.you_did_not_sleep));
|
||||
} else {
|
||||
if (!pieData.getSleepSessions().isEmpty()) {
|
||||
for (SleepSession sleepSession : pieData.getSleepSessions()) {
|
||||
if (result.length() > 0) {
|
||||
result.append('\n');
|
||||
result.append(" | ");
|
||||
}
|
||||
result.append(getContext().getString(
|
||||
R.string.you_slept,
|
||||
DateTimeUtils.timeToString(sleepSession.getSleepStart()),
|
||||
DateTimeUtils.timeToString(sleepSession.getSleepEnd())));
|
||||
String from = DateTimeUtils.timeToString(sleepSession.getSleepStart());
|
||||
String to = DateTimeUtils.timeToString(sleepSession.getSleepEnd());
|
||||
result.append(String.format("%s - %s", from, to));
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
@ -323,33 +350,26 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_sleepchart, container, false);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
rootView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
|
||||
getChartsHost().enableSwipeRefresh(scrollY == 0);
|
||||
});
|
||||
}
|
||||
|
||||
mActivityChart = rootView.findViewById(R.id.sleepchart);
|
||||
mSleepAmountChart = rootView.findViewById(R.id.sleepchart_pie_light_deep);
|
||||
mSleepchartInfo = rootView.findViewById(R.id.sleepchart_info);
|
||||
heartRateIcon = rootView.findViewById(R.id.heartrate_widget_icon);
|
||||
heartRateAverageLabel = rootView.findViewById(R.id.heartrate_widget_label);
|
||||
intensityTotalIcon = rootView.findViewById(R.id.intensity_widget_icon);
|
||||
intensityTotalLabel = rootView.findViewById(R.id.intensity_widget_label);
|
||||
remSleepTimeText = rootView.findViewById(R.id.sleep_chart_legend_rem_time);
|
||||
remSleepTimeTextWrapper = rootView.findViewById(R.id.sleep_chart_legend_rem_time_wrapper);
|
||||
deepSleepTimeText = rootView.findViewById(R.id.sleep_chart_legend_deep_time);
|
||||
lightSleepTimeText = rootView.findViewById(R.id.sleep_chart_legend_light_time);
|
||||
lowestHrText = rootView.findViewById(R.id.sleep_hr_lowest);
|
||||
highestHrText = rootView.findViewById(R.id.sleep_hr_highest);
|
||||
movementIntensityText = rootView.findViewById(R.id.sleep_movement_intensity);
|
||||
sleepDateText = rootView.findViewById(R.id.sleep_date);
|
||||
|
||||
ConstraintLayout intensityTotalWidgetLayout = rootView.findViewById(R.id.intensity_widget_layout);
|
||||
ConstraintLayout heartRateWidgetLayout = rootView.findViewById(R.id.heartrate_widget_layout);
|
||||
mSleepchartInfo.setMaxLines(sleepLinesLimit);
|
||||
|
||||
View.OnClickListener listener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
DecimalFormat df = new DecimalFormat("###.#");
|
||||
String detailedDuration = String.format(getString(R.string.charts_min_max_heartrate_popup), heartRateMin, heartRateMax, df.format(intensityTotal));
|
||||
new ShowDurationDialog(detailedDuration, getContext()).show();
|
||||
}
|
||||
};
|
||||
|
||||
heartRateWidgetLayout.setOnClickListener(listener);
|
||||
intensityTotalWidgetLayout.setOnClickListener(listener);
|
||||
intensityTotalIcon.setOnClickListener(listener);
|
||||
intensityTotalLabel.setOnClickListener(listener);
|
||||
|
||||
|
||||
setupActivityChart();
|
||||
setupSleepAmountChart();
|
||||
|
||||
@ -438,9 +458,6 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
legendEntries.add(remSleepEntry);
|
||||
}
|
||||
|
||||
heartRateIcon.setVisibility(View.GONE); //hide heart icon
|
||||
intensityTotalIcon.setVisibility(View.GONE); //hide intensity icon
|
||||
|
||||
if (supportsHeartrate(getChartsHost().getDevice())) {
|
||||
LegendEntry hrEntry = new LegendEntry();
|
||||
hrEntry.label = HEARTRATE_LABEL;
|
||||
@ -451,8 +468,6 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
hrAverageEntry.label = HEARTRATE_AVERAGE_LABEL;
|
||||
hrAverageEntry.formColor = Color.RED;
|
||||
legendEntries.add(hrAverageEntry);
|
||||
heartRateIcon.setVisibility(View.VISIBLE);
|
||||
intensityTotalIcon.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
chart.getLegend().setCustom(legendEntries);
|
||||
@ -474,13 +489,19 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
|
||||
private static class MySleepChartsData extends ChartsData {
|
||||
private String totalSleep;
|
||||
private String totalRem;
|
||||
private String totalDeep;
|
||||
private String totalLight;
|
||||
private final PieData pieData;
|
||||
private final List<SleepSession> sleepSessions;
|
||||
|
||||
public MySleepChartsData(String totalSleep, PieData pieData, List<SleepSession> sleepSessions) {
|
||||
this.totalSleep = totalSleep;
|
||||
public MySleepChartsData(PieData pieData, List<SleepSession> sleepSessions, String totalSleep, String totalRem, String totalDeep, String totalLight) {
|
||||
this.pieData = pieData;
|
||||
this.sleepSessions = sleepSessions;
|
||||
this.totalSleep = totalSleep;
|
||||
this.totalRem = totalRem;
|
||||
this.totalDeep = totalDeep;
|
||||
this.totalLight = totalLight;
|
||||
}
|
||||
|
||||
public PieData getPieData() {
|
||||
@ -491,6 +512,18 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
||||
return totalSleep;
|
||||
}
|
||||
|
||||
public CharSequence getTotalRem() {
|
||||
return totalRem;
|
||||
}
|
||||
|
||||
public CharSequence getTotalDeep() {
|
||||
return totalDeep;
|
||||
}
|
||||
|
||||
public CharSequence getTotalLight() {
|
||||
return totalLight;
|
||||
}
|
||||
|
||||
public List<SleepSession> getSleepSessions() {
|
||||
return sleepSessions;
|
||||
}
|
||||
|
@ -17,14 +17,27 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.LegendEntry;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -37,6 +50,122 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
|
||||
public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
|
||||
private TextView remSleepTimeText;
|
||||
private LinearLayout remSleepTimeTextWrapper;
|
||||
private TextView deepSleepTimeText;
|
||||
private TextView lightSleepTimeText;
|
||||
private TextView sleepDatesText;
|
||||
private MySleepWeeklyData mySleepWeeklyData;
|
||||
|
||||
private MySleepWeeklyData getMySleepWeeklyData(DBHandler db, Calendar day, GBDevice device) {
|
||||
day = (Calendar) day.clone(); // do not modify the caller's argument
|
||||
day.add(Calendar.DATE, -TOTAL_DAYS + 1);
|
||||
TOTAL_DAYS_FOR_AVERAGE=0;
|
||||
long remWeeklyTotal = 0;
|
||||
long deepWeeklyTotal = 0;
|
||||
long lightWeeklyTotal = 0;
|
||||
|
||||
for (int counter = 0; counter < TOTAL_DAYS; counter++) {
|
||||
ActivityAmounts amounts = getActivityAmountsForDay(db, day, device);
|
||||
if (calculateBalance(amounts) > 0) {
|
||||
TOTAL_DAYS_FOR_AVERAGE++;
|
||||
}
|
||||
|
||||
float[] totalAmounts = getTotalsForActivityAmounts(amounts);
|
||||
deepWeeklyTotal += (long) totalAmounts[0];
|
||||
lightWeeklyTotal += (long) totalAmounts[1];
|
||||
if (supportsRemSleep(device)) {
|
||||
remWeeklyTotal += (long) totalAmounts[2];
|
||||
}
|
||||
day.add(Calendar.DATE, 1);
|
||||
}
|
||||
|
||||
return new MySleepWeeklyData(remWeeklyTotal, deepWeeklyTotal, lightWeeklyTotal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
mLocale = getResources().getConfiguration().locale;
|
||||
View rootView = inflater.inflate(R.layout.fragment_weeksleep_chart, container, false);
|
||||
|
||||
final int goal = getGoal();
|
||||
if (goal >= 0) {
|
||||
mTargetValue = goal;
|
||||
}
|
||||
|
||||
mWeekChart = rootView.findViewById(R.id.weekstepschart);
|
||||
remSleepTimeText = rootView.findViewById(R.id.sleep_chart_legend_rem_time);
|
||||
remSleepTimeTextWrapper = rootView.findViewById(R.id.sleep_chart_legend_rem_time_wrapper);
|
||||
deepSleepTimeText = rootView.findViewById(R.id.sleep_chart_legend_deep_time);
|
||||
lightSleepTimeText = rootView.findViewById(R.id.sleep_chart_legend_light_time);
|
||||
sleepDatesText = rootView.findViewById(R.id.sleep_dates);
|
||||
|
||||
setupWeekChart();
|
||||
|
||||
// refresh immediately instead of use refreshIfVisible(), for perceived performance
|
||||
refresh();
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateChartsnUIThread(MyChartsData mcd) {
|
||||
setupLegend(mWeekChart);
|
||||
|
||||
//set custom renderer for 30days bar charts
|
||||
if (GBApplication.getPrefs().getBoolean("charts_range", true)) {
|
||||
mWeekChart.setRenderer(new AngledLabelsChartRenderer(mWeekChart, mWeekChart.getAnimator(), mWeekChart.getViewPortHandler()));
|
||||
}
|
||||
|
||||
mWeekChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
|
||||
mWeekChart.setData(mcd.getWeekBeforeData().getData());
|
||||
mWeekChart.getXAxis().setValueFormatter(mcd.getWeekBeforeData().getXValueFormatter());
|
||||
mWeekChart.getBarData().setValueTextSize(14f);
|
||||
mWeekChart.setScaleEnabled(false);
|
||||
mWeekChart.setTouchEnabled(false);
|
||||
|
||||
if (TOTAL_DAYS_FOR_AVERAGE > 0) {
|
||||
float avgDeep = Math.abs(this.mySleepWeeklyData.getTotalDeep() / TOTAL_DAYS_FOR_AVERAGE);
|
||||
deepSleepTimeText.setText(DateTimeUtils.formatDurationHoursMinutes((int) avgDeep, TimeUnit.MINUTES));
|
||||
float avgLight = Math.abs(this.mySleepWeeklyData.getTotalLight() / TOTAL_DAYS_FOR_AVERAGE);
|
||||
lightSleepTimeText.setText(DateTimeUtils.formatDurationHoursMinutes((int) avgLight, TimeUnit.MINUTES));
|
||||
float avgRem = Math.abs(this.mySleepWeeklyData.getTotalRem() / TOTAL_DAYS_FOR_AVERAGE);
|
||||
remSleepTimeText.setText(DateTimeUtils.formatDurationHoursMinutes((int) avgRem, TimeUnit.MINUTES));
|
||||
} else {
|
||||
deepSleepTimeText.setText("-");
|
||||
lightSleepTimeText.setText("-");
|
||||
remSleepTimeText.setText("-");
|
||||
}
|
||||
|
||||
if (!supportsRemSleep(getChartsHost().getDevice())) {
|
||||
remSleepTimeTextWrapper.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Date to = new Date((long) this.getTSEnd() * 1000);
|
||||
Date from = DateUtils.addDays(to,-(TOTAL_DAYS - 1));
|
||||
String toFormattedDate = new SimpleDateFormat("E, MMM dd").format(to);
|
||||
String fromFormattedDate = new SimpleDateFormat("E, MMM dd").format(from);
|
||||
sleepDatesText.setText(fromFormattedDate + " - " + toFormattedDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MyChartsData refreshInBackground(ChartsHost chartsHost, DBHandler db, GBDevice device) {
|
||||
Calendar day = Calendar.getInstance();
|
||||
day.setTime(chartsHost.getEndDate());
|
||||
//NB: we could have omitted the day, but this way we can move things to the past easily
|
||||
WeekChartsData<BarData> weekBeforeData = refreshWeekBeforeData(db, mWeekChart, day, device);
|
||||
mySleepWeeklyData = getMySleepWeeklyData(db, day, device);
|
||||
|
||||
return new MyChartsData(null, weekBeforeData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderCharts() {
|
||||
mWeekChart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
if (GBApplication.getPrefs().getBoolean("charts_range", true)) {
|
||||
@ -205,4 +334,33 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
return getHM((long)value);
|
||||
}
|
||||
|
||||
private static class MySleepWeeklyData {
|
||||
private long totalRem;
|
||||
private long totalDeep;
|
||||
private long totalLight;
|
||||
private int totalDaysForAverage;
|
||||
|
||||
public MySleepWeeklyData(long totalRem, long totalDeep, long totalLight) {
|
||||
this.totalDeep = totalDeep;
|
||||
this.totalRem = totalRem;
|
||||
this.totalLight = totalLight;
|
||||
this.totalDaysForAverage = 0;
|
||||
}
|
||||
|
||||
public long getTotalRem() {
|
||||
return this.totalRem;
|
||||
}
|
||||
|
||||
public long getTotalDeep() {
|
||||
return this.totalDeep;
|
||||
}
|
||||
|
||||
public long getTotalLight() {
|
||||
return this.totalLight;
|
||||
}
|
||||
|
||||
public int getTotalDaysForAverage() {
|
||||
return this.totalDaysForAverage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ public abstract class AbstractDashboardWidget extends Fragment {
|
||||
protected @ColorInt int color_worn = Color.rgb(128, 128, 128);
|
||||
protected @ColorInt int color_activity = Color.GREEN;
|
||||
protected @ColorInt int color_exercise = Color.rgb(255, 128, 0);
|
||||
protected @ColorInt int color_deep_sleep = Color.BLUE;
|
||||
protected @ColorInt int color_light_sleep = Color.rgb(150, 150, 255);
|
||||
protected @ColorInt int color_rem_sleep = Color.rgb(182, 191, 255);
|
||||
protected @ColorInt int color_deep_sleep = Color.rgb(0, 84, 163);
|
||||
protected @ColorInt int color_light_sleep = Color.rgb(7, 158, 243);
|
||||
protected @ColorInt int color_rem_sleep = Color.rgb(228, 39, 199);
|
||||
protected @ColorInt int color_distance = Color.BLUE;
|
||||
protected @ColorInt int color_active_time = Color.rgb(170, 0, 255);
|
||||
|
||||
|
@ -54,10 +54,11 @@ public class ActivityKind {
|
||||
public static final int TYPE_HIKING = 0x00400000;
|
||||
public static final int TYPE_CLIMBING = 0x00800000;
|
||||
public static final int TYPE_REM_SLEEP = 0x01000000;
|
||||
public static final int TYPE_AWAKE_SLEEP = 0x02000000;
|
||||
|
||||
private static final int TYPES_COUNT = 26;
|
||||
|
||||
public static final int TYPE_SLEEP = TYPE_LIGHT_SLEEP | TYPE_DEEP_SLEEP | TYPE_REM_SLEEP;
|
||||
public static final int TYPE_SLEEP = TYPE_LIGHT_SLEEP | TYPE_DEEP_SLEEP | TYPE_REM_SLEEP | TYPE_AWAKE_SLEEP;
|
||||
public static final int TYPE_ALL = TYPE_ACTIVITY | TYPE_SLEEP | TYPE_NOT_WORN;
|
||||
|
||||
public static int[] mapToDBActivityTypes(int types, SampleProvider provider) {
|
||||
|
@ -1,53 +1,266 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ActivityChartsActivity$PlaceholderFragment">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleepchart_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:id="@+id/sleep_date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true"
|
||||
android:scrollbarFadeDuration="0"
|
||||
android:scrollbars="vertical" />
|
||||
android:layout_marginTop="15dp"
|
||||
android:gravity="center"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleepchart_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="-"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<com.github.mikephil.charting.charts.PieChart
|
||||
android:id="@+id/sleepchart_pie_light_deep"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_weight="2" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:layout_weight="3"
|
||||
android:shrinkColumns="*"
|
||||
android:stretchColumns="*">
|
||||
|
||||
<TableRow
|
||||
android:id="@+id/tableRow1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:weightSum="2">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="20dip"
|
||||
android:paddingTop="20dip"
|
||||
android:paddingRight="20dip">
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="5dp"
|
||||
android:background="@color/chart_deep_sleep_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_deep_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:layout_marginTop="20dip"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_deep_legend"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:text="@string/sleep_colored_stats_deep"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="20dip"
|
||||
android:paddingTop="20dip"
|
||||
android:paddingRight="20dip">
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="5dp"
|
||||
android:background="@color/chart_light_sleep_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_light_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:layout_marginTop="20dip"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_light_legend"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:text="@string/sleep_colored_stats_light"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:id="@+id/tableRow2"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:weightSum="2">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/sleep_chart_legend_rem_time_wrapper"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="20dip"
|
||||
android:paddingTop="20dip"
|
||||
android:paddingRight="20dip">
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="5dp"
|
||||
android:background="@color/chart_rem_sleep_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_rem_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:layout_marginTop="20dip"
|
||||
android:gravity="center"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_rem_legend"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:gravity="center"
|
||||
android:text="@string/sleep_colored_stats_rem"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/secondarytext" />
|
||||
|
||||
<GridLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="5dip">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_hr_lowest"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="20dip"
|
||||
android:gravity="center"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/stats_lowest_hr"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="5dip">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_hr_highest"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="20dip"
|
||||
android:gravity="center"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/stats_highest_hr"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="5dip">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_movement_intensity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="20dip"
|
||||
android:gravity="center"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/movement_intensity"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
</GridLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:background="@color/secondarytext" />
|
||||
|
||||
<com.github.mikephil.charting.charts.LineChart
|
||||
android:id="@+id/sleepchart"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="2" />
|
||||
android:layout_height="300dp"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:layout_weight="4" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/layout_widget_heartrate_average"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_gravity="top|end" />
|
||||
|
||||
<include
|
||||
layout="@layout/layout_widget_intensity_total"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginTop="50dp"
|
||||
android:layout_marginEnd="-1dp"
|
||||
android:layout_gravity="top|end" />
|
||||
</RelativeLayout>
|
||||
</ScrollView>
|
155
app/src/main/res/layout/fragment_weeksleep_chart.xml
Normal file
155
app/src/main/res/layout/fragment_weeksleep_chart.xml
Normal file
@ -0,0 +1,155 @@
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ActivityChartsActivity$PlaceholderFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sleep_dates"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textSize="20sp"
|
||||
android:layout_marginTop="15dp"
|
||||
/>
|
||||
|
||||
<TableLayout
|
||||
android:layout_weight="3"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0dp"
|
||||
android:shrinkColumns="*"
|
||||
android:stretchColumns="*"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
>
|
||||
<TableRow
|
||||
android:id="@+id/tableRow1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:weightSum="2"
|
||||
>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="20dip"
|
||||
android:paddingLeft="20dip"
|
||||
android:paddingRight="20dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
>
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="5dp"
|
||||
android:background="@color/chart_deep_sleep_dark"/>
|
||||
<TextView
|
||||
android:layout_marginTop="20dip"
|
||||
android:id="@+id/sleep_chart_legend_deep_time"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp"
|
||||
android:layout_gravity="start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_deep_legend"
|
||||
android:text="@string/sleep_colored_stats_deep_avg"
|
||||
android:textSize="12sp"
|
||||
android:layout_gravity="start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="20dip"
|
||||
android:paddingLeft="20dip"
|
||||
android:paddingRight="20dip"
|
||||
android:gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
>
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="5dp"
|
||||
android:background="@color/chart_light_sleep_dark"/>
|
||||
<TextView
|
||||
android:layout_marginTop="20dip"
|
||||
android:id="@+id/sleep_chart_legend_light_time"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp"
|
||||
android:layout_gravity="start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_light_legend"
|
||||
android:text="@string/sleep_colored_stats_light_avg"
|
||||
android:textSize="12sp"
|
||||
android:layout_gravity="start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
android:id="@+id/tableRow2"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:weightSum="2"
|
||||
>
|
||||
<LinearLayout
|
||||
android:id="@+id/sleep_chart_legend_rem_time_wrapper"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="20dip"
|
||||
android:paddingLeft="20dip"
|
||||
android:paddingRight="20dip"
|
||||
android:gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
>
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="5dp"
|
||||
android:background="@color/chart_rem_sleep_dark"/>
|
||||
<TextView
|
||||
android:layout_marginTop="20dip"
|
||||
android:id="@+id/sleep_chart_legend_rem_time"
|
||||
android:text="@string/stats_empty_value"
|
||||
android:textSize="20sp"
|
||||
android:layout_gravity="start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"/>
|
||||
<TextView
|
||||
android:id="@+id/sleep_chart_legend_rem_legend"
|
||||
android:text="@string/sleep_colored_stats_rem_avg"
|
||||
android:textSize="12sp"
|
||||
android:layout_gravity="start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"/>
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
|
||||
<com.github.mikephil.charting.charts.BarChart
|
||||
android:id="@+id/weekstepschart"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="350dp"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
@ -21,14 +21,15 @@
|
||||
<color name="chart_heartrate" type="color">#ffab40</color>
|
||||
<color name="chart_heartrate_alternative" type="color">#8B0000</color>
|
||||
<color name="chart_heartrate_fill" type="color">#fadab1</color>
|
||||
<color name="chart_deep_sleep_light" type="color">#0071b7</color>
|
||||
<color name="chart_deep_sleep_dark" type="color">#4c5aff</color>
|
||||
|
||||
<color name="chart_light_sleep_light" type="color">#46acea</color>
|
||||
<color name="chart_light_sleep_dark" type="color">#b6bfff</color>
|
||||
<color name="chart_deep_sleep_light" type="color">#0054a3</color>
|
||||
<color name="chart_deep_sleep_dark" type="color">#0054a3</color>
|
||||
|
||||
<color name="chart_rem_sleep_light" type="color">#b6bfff</color>
|
||||
<color name="chart_rem_sleep_dark" type="color">#46acea</color>
|
||||
<color name="chart_light_sleep_light" type="color">#079ef3</color>
|
||||
<color name="chart_light_sleep_dark" type="color">#079ef3</color>
|
||||
|
||||
<color name="chart_rem_sleep_light" type="color">#e427c7</color>
|
||||
<color name="chart_rem_sleep_dark" type="color">#e427c7</color>
|
||||
|
||||
<color name="chart_activity_light" type="color">#60bd6d</color>
|
||||
<color name="chart_activity_dark" type="color">#59b22c</color>
|
||||
@ -39,6 +40,8 @@
|
||||
<color name="alternate_row_background_light">#FFEDEDED</color>
|
||||
<color name="alternate_row_background_dark">#545254</color>
|
||||
|
||||
<color name="transparent">#00000000</color>
|
||||
|
||||
<drawable name="selected">@color/accent</drawable>
|
||||
|
||||
</resources>
|
@ -951,8 +951,18 @@
|
||||
<string name="abstract_chart_fragment_kind_light_sleep">Light sleep</string>
|
||||
<string name="abstract_chart_fragment_kind_deep_sleep">Deep sleep</string>
|
||||
<string name="abstract_chart_fragment_kind_rem_sleep">REM sleep</string>
|
||||
<string name="abstract_chart_fragment_kind_awake_sleep">Awake sleep</string>
|
||||
<string name="abstract_chart_fragment_kind_not_worn">Not worn</string>
|
||||
<string name="you_slept">You slept from %1$s to %2$s</string>
|
||||
<string name="sleep_colored_stats_deep">Deep</string>
|
||||
<string name="sleep_colored_stats_light">Light</string>
|
||||
<string name="sleep_colored_stats_rem">REM</string>
|
||||
<string name="sleep_colored_stats_deep_avg">Deep AVG</string>
|
||||
<string name="sleep_colored_stats_light_avg">Light AVG</string>
|
||||
<string name="sleep_colored_stats_rem_avg">REM AVG</string>
|
||||
<string name="stats_empty_value">-</string>
|
||||
<string name="stats_lowest_hr">Lowest HR</string>
|
||||
<string name="stats_highest_hr">Highest HR</string>
|
||||
<string name="you_slept">%1$s - %2$s</string>
|
||||
<string name="you_did_not_sleep">You did not sleep</string>
|
||||
<string name="charts_min_max_heartrate_popup">Lowest heart rate: %1$d \nHighest heart rate: %2$d \nMovement intensity: %3$s</string>
|
||||
<string name="device_not_connected">Not connected.</string>
|
||||
|
Loading…
Reference in New Issue
Block a user