mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-24 19:06:53 +01:00
Add Activity List Dashboard/Summary view
This commit is contained in:
parent
9c90452f92
commit
551a5c1a66
102
app/src/main/assets/activity_stacked.svg
Normal file
102
app/src/main/assets/activity_stacked.svg
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="26"
|
||||
height="26"
|
||||
tint="#7E7E7E"
|
||||
viewportWidth="25"
|
||||
viewportHeight="25"
|
||||
version="1.1"
|
||||
id="svg1967"
|
||||
sodipodi:docname="activity_stacked.svg"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
|
||||
<metadata
|
||||
id="metadata1973">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs1971" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1042"
|
||||
id="namedview1969"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="1.5628297"
|
||||
inkscape:cy="3.351769"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="38"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g5608"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:snap-nodes="false">
|
||||
<sodipodi:guide
|
||||
position="18.131447,189.15957"
|
||||
orientation="0,-1"
|
||||
id="guide2551" />
|
||||
<sodipodi:guide
|
||||
position="6.8118842,20.241473"
|
||||
orientation="1,0"
|
||||
id="guide2553" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
id="g5608"
|
||||
transform="matrix(0.6107681,0,0,0.6107681,-0.50776959,-2.4214301)"
|
||||
style="stroke-width:1.63728">
|
||||
<g
|
||||
id="g2806"
|
||||
transform="matrix(1.8819341,0,-1.0509142,4.0780968,7.7001407,-9.1852646)"
|
||||
style="stroke-width:0.591009">
|
||||
<g
|
||||
id="g2123"
|
||||
transform="matrix(1,0,0,0.33594705,0,3.7327618)"
|
||||
style="stroke-width:1.01966;stroke-miterlimit:4;stroke-dasharray:none">
|
||||
<path
|
||||
fill="#000000"
|
||||
d="m 12,18 a 6,6 0 0 1 -6,-6 6,6 0 0 1 6,-6 6,6 0 0 1 6,6 6,6 0 0 1 -6,6 M 20,15.31 23.31,12 20,8.69 V 4 H 15.31 L 12,0.69 8.69,4 H 4 V 8.69 L 0.69,12 4,15.31 V 20 H 8.69 L 12,23.31 15.31,20 H 20 Z"
|
||||
id="path1965"
|
||||
style="stroke-width:1.01966;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="m 4.4762317,12.388718 h 3.561751 l 2.0837443,-5.0286723 1.932068,5.4893343 1.823648,-2.726785 h 6.48905 l -0.488068,1.38717 H 14.61543 l -2.938854,4.509156 -1.60202,-4.54569 -0.9505983,2.403348 -3.506487,-4.01e-4 z"
|
||||
id="path2361"
|
||||
sodipodi:nodetypes="ccccccccccccc"
|
||||
style="stroke-width:1.01966;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
inkscape:transform-center-x="1.0957646"
|
||||
inkscape:transform-center-y="-1.4792654" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.591009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000"
|
||||
d="m 3.9815232,10.751128 v 0.490234 h 4.6484375 l 3.3515623,1.126953 3.349609,-1.126953 h 4.650391 v -0.490234 h -4.730469 l -3.269531,1.097656 -3.2714842,-1.097656 z"
|
||||
id="path2783" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.591009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000"
|
||||
d="m 3.9892109,11.549912 v 0.490234 h 4.6503907 l 3.3496094,1.126953 3.349609,-1.126953 h 4.650391 v -0.490234 h -4.730469 l -3.269531,1.097656 -3.2695313,-1.097656 z"
|
||||
id="path2787" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.2 KiB |
59
app/src/main/assets/ic_intensity_hollow.svg
Normal file
59
app/src/main/assets/ic_intensity_hollow.svg
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
version="1.1"
|
||||
id="svg6"
|
||||
sodipodi:docname="ic_intensity_hollow.svg"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1042"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="32.125"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="38"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg6" />
|
||||
<path
|
||||
d="M0 0h24v24H0V0z"
|
||||
fill="none"
|
||||
id="path2" />
|
||||
<path
|
||||
d="m 13.5,0.67 c 0,0 0.74,2.65 0.74,4.8 0,2.06 -1.35,3.73 -3.41,3.73 C 8.76,9.2 7.2,7.53 7.2,5.47 L 7.23,5.11 C 5.21,7.51 4,10.62 4,14 c 0,4.42 3.58,8 8,8 4.42,0 8,-3.58 8,-8 C 20,8.61 17.41,3.8 13.5,0.67 Z M 12,20 C 8.69,20 6,17.31 6,14 6,12.47 6.3,10.96 6.86,9.57 c 1.01,1.01 2.41,1.63 3.97,1.63 2.66,0 4.75,-1.83 5.28,-4.43 1.23,2.2 1.89,4.67 1.89,7.23 0,3.31 -2.69,6 -6,6 z"
|
||||
id="path4"
|
||||
sodipodi:nodetypes="cssccssscsscscss" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
70
app/src/main/assets/ic_shoe_prints_many.svg
Normal file
70
app/src/main/assets/ic_shoe_prints_many.svg
Normal file
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
id="svg4"
|
||||
sodipodi:docname="ic_shoe_prints_many.svg"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1042"
|
||||
id="namedview6"
|
||||
showgrid="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:zoom="16.0625"
|
||||
inkscape:cx="20.274468"
|
||||
inkscape:cy="17.69706"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="38"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4"
|
||||
inkscape:document-rotation="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid880" />
|
||||
<sodipodi:guide
|
||||
position="16,24"
|
||||
orientation="0,-1"
|
||||
id="guide882" />
|
||||
</sodipodi:namedview>
|
||||
<path
|
||||
d="m 6.4801431,14.379265 c 0.3823082,1.031063 0.3416371,2.10404 -0.8052874,2.531554 C 3.3159331,17.807761 2.787209,15.452241 2.7546721,15.334884 l 3.725471,-0.955619 M 2.3886324,13.700271 5.9026138,12.80333 c -0.1545501,-0.880176 0.081342,-1.760353 0.081342,-2.799798 0,-1.4082825 -1.0818507,-4.1661681 -2.8063045,-3.7218887 -1.9684802,0.5029579 -2.2531778,2.7578856 -2.1799698,3.8476277 0.097611,1.089742 1.3340114,3.420113 1.3909509,3.571 m 9.8749386,7.494073 C 12.239171,21.320083 11.70231,23.66722 9.343387,22.778661 8.204597,22.342764 8.155792,21.269787 8.5381,20.238724 l 3.725471,0.95562 m 1.748856,-5.197232 c 0.08134,-1.089742 -0.195221,-3.353052 -2.171836,-3.85601 -1.716319,-0.461045 -2.79817,2.313606 -2.79817,3.730271 0,1.031064 0.227758,1.91124 0.08948,2.791416 l 3.497713,0.896942 c 0.06507,-0.150888 1.293341,-2.481259 1.382817,-3.562619 z"
|
||||
id="path2"
|
||||
style="stroke-width:0.999999" />
|
||||
<path
|
||||
d="M 14.730838,7.4902842 C 14.986006,8.2347895 14.958862,9.00956 14.193361,9.3182576 12.618928,9.9659169 12.266038,8.2650539 12.244321,8.1803133 L 14.730838,7.4902842 M 12.000011,7 14.345374,6.3523407 c -0.103162,-0.6355538 0.05428,-1.2711071 0.05428,-2.0216657 0,-1.0168858 -0.722068,-3.0082871 -1.873034,-2.6874837 -1.313836,0.3631733 -1.503856,1.9914011 -1.454993,2.778277 C 11.136774,5.2083444 11.961996,6.8910478 12,7 m 6.590901,5.411286 c -0.0162,0.09079 -0.374605,1.785603 -1.949038,1.143996 -0.760065,-0.314751 -0.79264,-1.089521 -0.537473,-1.834026 l 2.486519,0.69003 m 1.16726,-3.7527936 c 0.05428,-0.7868766 -0.130305,-2.4211567 -1.449564,-2.78433 -1.145536,-0.3329091 -1.867604,1.670598 -1.867604,2.6935367 0,0.7445054 0.152015,1.3800583 0.05971,2.0156119 l 2.334511,0.647659 c 0.04345,-0.108954 0.863221,-1.7916547 0.922943,-2.5724776 z"
|
||||
id="path2-3"
|
||||
style="stroke-width:0.999998" />
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
@ -1,59 +1,273 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
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.PieChart;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.adapter.AbstractActivityListingAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
|
||||
public class ActivityListingAdapter extends AbstractActivityListingAdapter<StepAnalysis.StepSession> {
|
||||
public class ActivityListingAdapter extends AbstractActivityListingAdapter<ActivitySession> {
|
||||
public static final String ACTIVE_STEPS_CHART_COLOR = "#3498db";
|
||||
public static final String DISTANCE_CHART_COLOR = "#f1c40f";
|
||||
public static final String ACTIVE_TIME_CHART_COLOR = "#e74c3c";
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(AbstractWeekChartFragment.class);
|
||||
private final int SESSION_SUMMARY = ActivitySession.SESSION_SUMMARY;
|
||||
ActivityUser activityUser = new ActivityUser();
|
||||
int stepsGoal = activityUser.getStepsGoal();
|
||||
int distanceMeters = activityUser.getDistanceMeters();
|
||||
long activeTimeMillis = activityUser.getActiveTimeMinutes() * 60 * 1000L;
|
||||
|
||||
public ActivityListingAdapter(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDateLabel(StepAnalysis.StepSession item) {
|
||||
protected View fill_dashboard(ActivitySession item, int position, View view, ViewGroup parent, Context context) {
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
view = inflater.inflate(R.layout.activity_list_dashboard_item, parent, false);
|
||||
|
||||
PieChart ActiveStepsChart;
|
||||
PieChart DistanceChart;
|
||||
PieChart ActiveTimeChart;
|
||||
|
||||
ActiveStepsChart = view.findViewById(R.id.activity_dashboard_piechart1);
|
||||
setUpChart(ActiveStepsChart);
|
||||
setStepsData(item, ActiveStepsChart, context);
|
||||
|
||||
DistanceChart = view.findViewById(R.id.activity_dashboard_piechart2);
|
||||
setUpChart(DistanceChart);
|
||||
setDistanceData(item, DistanceChart, context);
|
||||
|
||||
ActiveTimeChart = view.findViewById(R.id.activity_dashboard_piechart3);
|
||||
setUpChart(ActiveTimeChart);
|
||||
setDurationData(item, ActiveTimeChart, context);
|
||||
|
||||
TextView stepLabel = view.findViewById(R.id.line_layout_step_label);
|
||||
TextView stepTotalLabel = view.findViewById(R.id.line_layout_total_step_label);
|
||||
|
||||
TextView distanceLabel = view.findViewById(R.id.line_layout_distance_label);
|
||||
|
||||
TextView hrLabel = view.findViewById(R.id.heartrate_widget_label);
|
||||
|
||||
TextView intensityLabel = view.findViewById(R.id.intensity_widget_label);
|
||||
TextView intensity2Label = view.findViewById(R.id.line_layout_intensity2_label);
|
||||
|
||||
|
||||
TextView durationLabel = view.findViewById(R.id.line_layout_duration_label);
|
||||
TextView sessionCountLabel = view.findViewById(R.id.line_layout_count_label);
|
||||
|
||||
LinearLayout durationLayout = view.findViewById(R.id.line_layout_duration);
|
||||
LinearLayout countLayout = view.findViewById(R.id.line_layout_count);
|
||||
|
||||
|
||||
View hrLayout = view.findViewById(R.id.heartrate_widget_icon);
|
||||
LinearLayout stepsLayout = view.findViewById(R.id.line_layout_step);
|
||||
LinearLayout stepsTotalLayout = view.findViewById(R.id.line_layout_total_step);
|
||||
|
||||
|
||||
LinearLayout distanceLayout = view.findViewById(R.id.line_layout_distance);
|
||||
View intensityLayout = view.findViewById(R.id.intensity_widget_icon);
|
||||
View intensity2Layout = view.findViewById(R.id.line_layout_intensity2);
|
||||
|
||||
stepLabel.setText(getStepLabel(item));
|
||||
stepTotalLabel.setText(getStepTotalLabel(item));
|
||||
|
||||
distanceLabel.setText(getDistanceLabel(item));
|
||||
hrLabel.setText(getHrLabel(item));
|
||||
intensityLabel.setText(getIntensityLabel(item));
|
||||
intensity2Label.setText(getIntensityLabel(item));
|
||||
durationLabel.setText(getDurationLabel(item));
|
||||
sessionCountLabel.setText(getSessionCountLabel(item));
|
||||
|
||||
if (!hasHR(item)) {
|
||||
hrLayout.setVisibility(View.GONE);
|
||||
hrLabel.setVisibility(View.GONE);
|
||||
} else {
|
||||
hrLayout.setVisibility(View.VISIBLE);
|
||||
hrLabel.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!hasIntensity(item)) {
|
||||
intensityLayout.setVisibility(View.GONE);
|
||||
intensity2Layout.setVisibility(View.GONE);
|
||||
intensityLabel.setVisibility(View.GONE);
|
||||
intensity2Label.setVisibility(View.GONE);
|
||||
} else {
|
||||
intensityLayout.setVisibility(View.VISIBLE);
|
||||
intensity2Layout.setVisibility(View.VISIBLE);
|
||||
intensityLabel.setVisibility(View.VISIBLE);
|
||||
intensity2Label.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!hasDistance(item)) {
|
||||
distanceLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
distanceLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!hasSteps(item)) {
|
||||
stepsLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
stepsLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!hasTotalSteps(item)) {
|
||||
stepsTotalLayout.setVisibility(View.GONE);
|
||||
countLayout.setVisibility(View.GONE);
|
||||
durationLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
stepsTotalLayout.setVisibility(View.VISIBLE);
|
||||
countLayout.setVisibility(View.VISIBLE);
|
||||
durationLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void setStepsData(ActivitySession item, PieChart DashboardChart, Context context) {
|
||||
ArrayList<PieEntry> entries = new ArrayList<>();
|
||||
int steps = item.getActiveSteps();
|
||||
entries.add(new PieEntry((float) steps));
|
||||
|
||||
if (steps < stepsGoal) {
|
||||
entries.add(new PieEntry((float) (stepsGoal - steps)));
|
||||
}
|
||||
|
||||
DashboardChart.setCenterText(String.format("%d%%\n%s", (int) (steps * 100 / stepsGoal), context.getString(R.string.activity_list_summary_active_steps)));
|
||||
|
||||
PieDataSet dataSet = new PieDataSet(entries, "");
|
||||
dataSet.setSliceSpace(0f);
|
||||
dataSet.setSelectionShift(5f);
|
||||
|
||||
dataSet.setColors(Color.parseColor(ACTIVE_STEPS_CHART_COLOR), Color.LTGRAY);
|
||||
PieData data = new PieData(dataSet);
|
||||
data.setValueTextSize(0f);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
DashboardChart.setData(data);
|
||||
DashboardChart.invalidate();
|
||||
}
|
||||
|
||||
private void setDistanceData(ActivitySession item, PieChart DashboardChart, Context context) {
|
||||
ArrayList<PieEntry> entries = new ArrayList<>();
|
||||
float distance = item.getDistance();
|
||||
entries.add(new PieEntry(distance));
|
||||
|
||||
if (distance < distanceMeters) {
|
||||
entries.add(new PieEntry((float) (distanceMeters - distance)));
|
||||
}
|
||||
|
||||
DashboardChart.setCenterText(String.format("%d%%\n%s", (int) (distance * 100 / distanceMeters), context.getString(R.string.distance)));
|
||||
PieDataSet dataSet = new PieDataSet(entries, "");
|
||||
dataSet.setSliceSpace(0f);
|
||||
dataSet.setSelectionShift(5f);
|
||||
|
||||
dataSet.setColors(Color.parseColor(DISTANCE_CHART_COLOR), Color.LTGRAY);
|
||||
PieData data = new PieData(dataSet);
|
||||
data.setValueTextSize(0f);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
DashboardChart.setData(data);
|
||||
DashboardChart.invalidate();
|
||||
}
|
||||
|
||||
private void setDurationData(ActivitySession item, PieChart DashboardChart, Context context) {
|
||||
ArrayList<PieEntry> entries = new ArrayList<>();
|
||||
long duration = item.getEndTime().getTime() - item.getStartTime().getTime();
|
||||
entries.add(new PieEntry((float) duration));
|
||||
|
||||
if (duration < activeTimeMillis) {
|
||||
entries.add(new PieEntry((float) (activeTimeMillis - duration)));
|
||||
}
|
||||
|
||||
DashboardChart.setCenterText(String.format("%d%%\n%s", (int) (duration * 100 / activeTimeMillis), context.getString(R.string.activity_list_summary_active_time)));
|
||||
PieDataSet dataSet = new PieDataSet(entries, "");
|
||||
dataSet.setSliceSpace(0f);
|
||||
dataSet.setSelectionShift(5f);
|
||||
dataSet.setColors(Color.parseColor(ACTIVE_TIME_CHART_COLOR), Color.LTGRAY);
|
||||
PieData data = new PieData(dataSet);
|
||||
data.setValueTextSize(0f);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
DashboardChart.setData(data);
|
||||
DashboardChart.invalidate();
|
||||
}
|
||||
|
||||
private void setUpChart(PieChart DashboardChart) {
|
||||
DashboardChart.setNoDataText("");
|
||||
DashboardChart.getLegend().setEnabled(false);
|
||||
DashboardChart.setDrawHoleEnabled(true);
|
||||
DashboardChart.setHoleColor(Color.WHITE);
|
||||
DashboardChart.getDescription().setText("");
|
||||
DashboardChart.setTransparentCircleColor(Color.WHITE);
|
||||
DashboardChart.setTransparentCircleAlpha(110);
|
||||
DashboardChart.setHoleRadius(70f);
|
||||
DashboardChart.setTransparentCircleRadius(75f);
|
||||
DashboardChart.setDrawCenterText(true);
|
||||
DashboardChart.setRotationEnabled(true);
|
||||
DashboardChart.setHighlightPerTapEnabled(true);
|
||||
DashboardChart.setCenterTextOffset(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDateLabel(ActivitySession item) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasGPS(StepAnalysis.StepSession item) {
|
||||
protected boolean hasGPS(ActivitySession item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasDate(StepAnalysis.StepSession item) {
|
||||
protected boolean hasDate(ActivitySession item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTimeFrom(StepAnalysis.StepSession item) {
|
||||
protected String getTimeFrom(ActivitySession item) {
|
||||
Date time = item.getStartTime();
|
||||
return DateTimeUtils.formatTime(time.getHours(), time.getMinutes());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTimeTo(StepAnalysis.StepSession item) {
|
||||
protected String getTimeTo(ActivitySession item) {
|
||||
Date time = item.getEndTime();
|
||||
return DateTimeUtils.formatTime(time.getHours(), time.getMinutes());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getActivityName(StepAnalysis.StepSession item) {
|
||||
protected String getActivityName(ActivitySession item) {
|
||||
return ActivityKind.asString(item.getActivityKind(), getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStepLabel(StepAnalysis.StepSession item) {
|
||||
return String.valueOf(item.getSteps());
|
||||
protected String getStepLabel(ActivitySession item) {
|
||||
return String.valueOf(item.getActiveSteps());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDistanceLabel(StepAnalysis.StepSession item) {
|
||||
protected String getDistanceLabel(ActivitySession item) {
|
||||
float distance = item.getDistance();
|
||||
String unit = "###m";
|
||||
if (distance > 2000) {
|
||||
@ -61,69 +275,74 @@ public class ActivityListingAdapter extends AbstractActivityListingAdapter<StepA
|
||||
unit = "###.#km";
|
||||
}
|
||||
DecimalFormat df = new DecimalFormat(unit);
|
||||
//DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
|
||||
//symbols.setGroupingSeparator(' ');
|
||||
return df.format(distance);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHrLabel(StepAnalysis.StepSession item) {
|
||||
protected String getHrLabel(ActivitySession item) {
|
||||
return String.valueOf(item.getHeartRateAverage());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getIntensityLabel(StepAnalysis.StepSession item) {
|
||||
DecimalFormat df = new DecimalFormat("###.#");
|
||||
protected String getIntensityLabel(ActivitySession item) {
|
||||
DecimalFormat df = new DecimalFormat("###");
|
||||
return df.format(item.getIntensity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDurationLabel(StepAnalysis.StepSession item) {
|
||||
protected String getDurationLabel(ActivitySession item) {
|
||||
long duration = item.getEndTime().getTime() - item.getStartTime().getTime();
|
||||
return DateTimeUtils.formatDurationHoursMinutes(duration, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHR(StepAnalysis.StepSession item) {
|
||||
if (item.getHeartRateAverage() > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
protected String getSessionCountLabel(ActivitySession item) {
|
||||
return String.valueOf(item.getSessionCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIntensity(StepAnalysis.StepSession item) {
|
||||
if (item.getIntensity() > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
public boolean hasHR(ActivitySession item) {
|
||||
return item.getHeartRateAverage() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasDistance(StepAnalysis.StepSession item) {
|
||||
if (item.getDistance() > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
public boolean hasIntensity(ActivitySession item) {
|
||||
return item.getIntensity() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasSteps(StepAnalysis.StepSession item) {
|
||||
if (item.getSteps() > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
protected boolean hasDistance(ActivitySession item) {
|
||||
return item.getDistance() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasSteps(ActivitySession item) {
|
||||
return item.getActiveSteps() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getIcon(StepAnalysis.StepSession item) {
|
||||
protected boolean hasTotalSteps(ActivitySession item) {
|
||||
return item.getTotalDaySteps() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSummary(ActivitySession item) {
|
||||
int sessionType = item.getSessionType();
|
||||
return sessionType == SESSION_SUMMARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEmptySummary(ActivitySession item) {
|
||||
return item.getIsEmptySummary();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStepTotalLabel(ActivitySession item) {
|
||||
return String.valueOf(item.getTotalDaySteps());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getIcon(ActivitySession item) {
|
||||
return ActivityKind.getIconId(item.getActivityKind());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -42,14 +42,14 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
|
||||
|
||||
public class ActivityListingChartFragment extends AbstractChartFragment {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(ActivityListingChartFragment.class);
|
||||
int tsDateFrom;
|
||||
|
||||
private View rootView;
|
||||
private List<? extends ActivitySample> activitySamples;
|
||||
private ActivityListingAdapter stepListAdapter;
|
||||
private TextView stepsDateView;
|
||||
|
||||
@ -57,18 +57,16 @@ public class ActivityListingChartFragment extends AbstractChartFragment {
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
rootView = inflater.inflate(R.layout.fragment_steps_list, container, false);
|
||||
|
||||
getChartsHost().enableSwipeRefresh(false);
|
||||
ListView stepsList = rootView.findViewById(R.id.itemListView);
|
||||
View headerView = inflater.inflate(R.layout.heartrate_average_widget,null, false);
|
||||
stepsList.addHeaderView(headerView);
|
||||
stepListAdapter = new ActivityListingAdapter(getContext());
|
||||
stepsList.setAdapter(stepListAdapter);
|
||||
stepsDateView = rootView.findViewById(R.id.stepsDateView);
|
||||
refresh();
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Steps list";
|
||||
@ -86,36 +84,40 @@ public class ActivityListingChartFragment extends AbstractChartFragment {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ChartsData refreshInBackground(ChartsHost chartsHost, DBHandler db, GBDevice device) {
|
||||
//trying to fit found peg into square hole of the Gb Charts fragment system
|
||||
//get the data
|
||||
List<? extends ActivitySample> activitySamples;
|
||||
activitySamples = getSamples(db, device);
|
||||
return null;
|
||||
List<ActivitySession> stepSessions = null;
|
||||
StepAnalysis stepAnalysis = new StepAnalysis();
|
||||
boolean isEmptySummary = false;
|
||||
|
||||
if (activitySamples != null) {
|
||||
stepSessions = stepAnalysis.calculateStepSessions(activitySamples);
|
||||
if (stepSessions.toArray().length == 0) {
|
||||
isEmptySummary = true;
|
||||
}
|
||||
stepSessions = stepAnalysis.calculateSummary(stepSessions, isEmptySummary);
|
||||
}
|
||||
return new MyChartsData(stepSessions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateChartsnUIThread(ChartsData chartsData) {
|
||||
//top displays selected date
|
||||
stepsDateView.setText(DateTimeUtils.formatDate(new Date(tsDateFrom * 1000L)));
|
||||
//calculate active sessions
|
||||
StepAnalysis stepAnalysis = new StepAnalysis();
|
||||
if (activitySamples != null) {
|
||||
List<StepAnalysis.StepSession> stepSessions = stepAnalysis.calculateStepSessions(activitySamples);
|
||||
if (stepSessions.toArray().length == 0) {
|
||||
stepSessions = create_empty_record();
|
||||
getChartsHost().enableSwipeRefresh(true); //try to enable pull to refresh, might be needed
|
||||
} else {
|
||||
getChartsHost().enableSwipeRefresh(false); //disable pull to refresh as it collides with swipable view
|
||||
}
|
||||
//push to the adapter
|
||||
stepListAdapter.setItems(stepSessions, true);
|
||||
MyChartsData mcd = (MyChartsData) chartsData;
|
||||
if (mcd.getStepSessions().toArray().length == 0) {
|
||||
getChartsHost().enableSwipeRefresh(true); //try to enable pull to refresh, might be needed
|
||||
} else {
|
||||
getChartsHost().enableSwipeRefresh(false); //disable pull to refresh as it collides with swipable view
|
||||
}
|
||||
|
||||
stepsDateView.setText(DateTimeUtils.formatDate(new Date(tsDateFrom * 1000L)));
|
||||
stepListAdapter.setItems(mcd.getStepSessions(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderCharts() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -135,16 +137,17 @@ public class ActivityListingChartFragment extends AbstractChartFragment {
|
||||
return getAllSamples(db, device, tsFrom, tsTo);
|
||||
}
|
||||
|
||||
private List<StepAnalysis.StepSession> create_empty_record() {
|
||||
//have an "Unknown Activity" in the list in case there are no active sessions
|
||||
List<StepAnalysis.StepSession> result = new ArrayList<>();
|
||||
int tsTo = tsDateFrom + 24 * 60 * 60 - 1;
|
||||
if (DateUtils.isToday(tsDateFrom * 1000L)) {
|
||||
Calendar day = Calendar.getInstance();
|
||||
day.set(Calendar.SECOND, 0);
|
||||
tsTo = (int) (day.getTimeInMillis() / 1000);
|
||||
private static class MyChartsData extends ChartsData {
|
||||
private final List<ActivitySession> stepSessions;
|
||||
|
||||
MyChartsData(List<ActivitySession> stepSessions) {
|
||||
this.stepSessions = stepSessions;
|
||||
}
|
||||
|
||||
public List<ActivitySession> getStepSessions() {
|
||||
return stepSessions;
|
||||
}
|
||||
result.add(new StepAnalysis.StepSession(new Date(tsDateFrom * 1000L), new Date(tsTo * 1000L), 0, 0, 0, 0, ActivityKind.TYPE_UNKNOWN));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -244,7 +243,7 @@ public class SleepChartFragment extends AbstractChartFragment {
|
||||
int min = Collections.min(heartRateValues);
|
||||
int max = Collections.max(heartRateValues);
|
||||
int count = heartRateValues.toArray().length;
|
||||
float sum = calculateHRSum(heartRateValues);
|
||||
float sum = calculateSumOfInts(heartRateValues);
|
||||
float average = sum / count;
|
||||
return Triple.of(average, min, max);
|
||||
}
|
||||
@ -257,7 +256,7 @@ public class SleepChartFragment extends AbstractChartFragment {
|
||||
return result;
|
||||
}
|
||||
|
||||
private float calculateHRSum(List<Integer> samples) {
|
||||
private float calculateSumOfInts(List<Integer> samples) {
|
||||
float result = 0;
|
||||
for (Integer sample : samples) {
|
||||
result += sample;
|
||||
|
@ -28,12 +28,14 @@ import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySession;
|
||||
|
||||
public class StepAnalysis {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(StepAnalysis.class);
|
||||
private int totalDailySteps = 0;
|
||||
|
||||
public List<StepSession> calculateStepSessions(List<? extends ActivitySample> samples) {
|
||||
List<StepSession> result = new ArrayList<>();
|
||||
public List<ActivitySession> calculateStepSessions(List<? extends ActivitySample> samples) {
|
||||
List<ActivitySession> result = new ArrayList<>();
|
||||
ActivityUser activityUser = new ActivityUser();
|
||||
double STEP_LENGTH_M;
|
||||
final int MIN_SESSION_LENGTH = 60 * GBApplication.getPrefs().getInt("chart_list_min_session_length", 5);
|
||||
@ -41,6 +43,7 @@ public class StepAnalysis {
|
||||
final int MIN_STEPS_PER_MINUTE = GBApplication.getPrefs().getInt("chart_list_min_steps_per_minute", 40);
|
||||
int stepLengthCm = activityUser.getStepLengthCm();
|
||||
int heightCm = activityUser.getHeightCm();
|
||||
totalDailySteps = 0;
|
||||
|
||||
if (stepLengthCm == 0 && heightCm != 0) {
|
||||
STEP_LENGTH_M = heightCm * 0.43 * 0.01;
|
||||
@ -68,6 +71,11 @@ public class StepAnalysis {
|
||||
HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance();
|
||||
|
||||
for (ActivitySample sample : samples) {
|
||||
int steps = sample.getSteps();
|
||||
if (steps > 0) {
|
||||
totalDailySteps += steps;
|
||||
}
|
||||
|
||||
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
|
||||
if (heartRateUtilsInstance.isValidHeartRateValue(sample.getHeartRate())) {
|
||||
@ -119,7 +127,7 @@ public class StepAnalysis {
|
||||
float distance = (float) (activeSteps * STEP_LENGTH_M);
|
||||
sessionEnd = new Date((sample.getTimestamp() - durationSinceLastActiveStep) * 1000L);
|
||||
activityKind = detect_activity_kind(session_length, activeSteps, heartRateAverage, activeIntensity);
|
||||
result.add(new StepSession(sessionStart, sessionEnd, activeSteps, heartRateAverage, activeIntensity, distance, activityKind));
|
||||
result.add(new ActivitySession(sessionStart, sessionEnd, activeSteps, heartRateAverage, activeIntensity, distance, activityKind));
|
||||
}
|
||||
sessionStart = null;
|
||||
}
|
||||
@ -139,12 +147,69 @@ public class StepAnalysis {
|
||||
float distance = (float) (activeSteps * STEP_LENGTH_M);
|
||||
sessionEnd = getDateFromSample(previousSample);
|
||||
activityKind = detect_activity_kind(session_length, activeSteps, heartRateAverage, activeIntensity);
|
||||
result.add(new StepSession(sessionStart, sessionEnd, activeSteps, heartRateAverage, activeIntensity, distance, activityKind));
|
||||
result.add(new ActivitySession(sessionStart, sessionEnd, activeSteps, heartRateAverage, activeIntensity, distance, activityKind));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<ActivitySession> calculateSummary(List<ActivitySession> sessions, boolean empty) {
|
||||
|
||||
HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance();
|
||||
Date startTime = null;
|
||||
Date endTime = null;
|
||||
int stepsSum = 0;
|
||||
int heartRateAverage = 0;
|
||||
List<Integer> heartRateSum = new ArrayList<>();
|
||||
int distanceSum = 0;
|
||||
float intensitySum = 0;
|
||||
int sessionCount;
|
||||
int durationSum = 0;
|
||||
|
||||
for (ActivitySession session : sessions) {
|
||||
startTime = session.getStartTime();
|
||||
endTime = session.getEndTime();
|
||||
durationSum += endTime.getTime() - startTime.getTime();
|
||||
stepsSum += session.getActiveSteps();
|
||||
distanceSum += session.getDistance();
|
||||
heartRateSum.add(session.getHeartRateAverage());
|
||||
intensitySum += session.getIntensity();
|
||||
}
|
||||
|
||||
sessionCount = sessions.toArray().length;
|
||||
if (heartRateSum.toArray().length > 0) {
|
||||
heartRateAverage = calculateSumOfInts(heartRateSum) / heartRateSum.toArray().length;
|
||||
}
|
||||
if (!heartRateUtilsInstance.isValidHeartRateValue(heartRateAverage)) {
|
||||
heartRateAverage = 0;
|
||||
}
|
||||
startTime = new Date(0);
|
||||
endTime = new Date(durationSum);
|
||||
|
||||
ActivitySession stepSessionSummary = new ActivitySession(startTime, endTime,
|
||||
stepsSum, heartRateAverage, intensitySum, distanceSum, 0);
|
||||
|
||||
stepSessionSummary.setSessionCount(sessionCount);
|
||||
stepSessionSummary.setSessionType(ActivitySession.SESSION_SUMMARY);
|
||||
stepSessionSummary.setEmptySummary(empty);
|
||||
|
||||
|
||||
stepSessionSummary.setTotalDaySteps(totalDailySteps);
|
||||
|
||||
List<ActivitySession> newList = new ArrayList<>();
|
||||
newList.add(stepSessionSummary);
|
||||
newList.addAll(sessions);
|
||||
return newList;
|
||||
}
|
||||
|
||||
private int calculateSumOfInts(List<Integer> samples) {
|
||||
int result = 0;
|
||||
for (Integer sample : samples) {
|
||||
result += sample;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int detect_activity_kind(int session_length, int activeSteps, int heartRateAverage, float intensity) {
|
||||
final int MIN_STEPS_PER_MINUTE_FOR_RUN = GBApplication.getPrefs().getInt("chart_list_min_steps_per_minute_for_run", 120);
|
||||
int spm = (int) (activeSteps / (session_length / 60));
|
||||
@ -160,61 +225,7 @@ public class StepAnalysis {
|
||||
return ActivityKind.TYPE_ACTIVITY;
|
||||
}
|
||||
|
||||
private boolean isStep(ActivitySample sample) {
|
||||
return sample.getKind() == ActivityKind.TYPE_WALKING || sample.getKind() == ActivityKind.TYPE_RUNNING || sample.getKind() == ActivityKind.TYPE_ACTIVITY;
|
||||
}
|
||||
|
||||
private Date getDateFromSample(ActivitySample sample) {
|
||||
return new Date(sample.getTimestamp() * 1000L);
|
||||
}
|
||||
|
||||
public static class StepSession {
|
||||
private final Date startTime;
|
||||
private final Date endTime;
|
||||
private final int steps;
|
||||
private final int heartRateAverage;
|
||||
private final float intensity;
|
||||
private final float distance;
|
||||
private final int activityKind;
|
||||
|
||||
StepSession(Date startTime,
|
||||
Date endTime,
|
||||
int steps, int heartRateAverage, float intensity, float distance, int activityKind) {
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
this.steps = steps;
|
||||
this.heartRateAverage = heartRateAverage;
|
||||
this.intensity = intensity;
|
||||
this.distance = distance;
|
||||
this.activityKind = activityKind;
|
||||
}
|
||||
|
||||
public Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public Date getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public int getSteps() {
|
||||
return steps;
|
||||
}
|
||||
|
||||
public int getHeartRateAverage() {
|
||||
return heartRateAverage;
|
||||
}
|
||||
|
||||
public int getActivityKind() {
|
||||
return activityKind;
|
||||
}
|
||||
|
||||
public float getIntensity() {
|
||||
return intensity;
|
||||
}
|
||||
|
||||
public float getDistance() {
|
||||
return distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.StepAnalysis;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySession;
|
||||
|
||||
/**
|
||||
* Adapter for displaying generic ItemWithDetails instances.
|
||||
@ -43,6 +45,7 @@ public abstract class AbstractActivityListingAdapter<T> extends ArrayAdapter<T>
|
||||
|
||||
private final Context context;
|
||||
private final List<T> items;
|
||||
private final int SESSION_SUMMARY = ActivitySession.SESSION_SUMMARY;
|
||||
private int backgroundColor = 0;
|
||||
private int alternateColor = 0;
|
||||
private boolean zebraStripes = true;
|
||||
@ -67,15 +70,27 @@ public abstract class AbstractActivityListingAdapter<T> extends ArrayAdapter<T>
|
||||
return typedValue.data;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View getView(int position, View view, ViewGroup parent) {
|
||||
T item = getItem(position);
|
||||
view = null; //this is ugly (probably we get no recycling), but it is required to keep the layout nice. We have only few items, so this should be OK.
|
||||
if (view == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
view = inflater.inflate(R.layout.activity_list_item, parent, false);
|
||||
|
||||
if (isSummary(item)) {
|
||||
view = fill_dashboard(item, position, view, parent, context);
|
||||
} else {
|
||||
view = fill_item(item, position, view, parent);
|
||||
}
|
||||
|
||||
return view;
|
||||
|
||||
|
||||
}
|
||||
|
||||
private View fill_item(T item, int position, View view, ViewGroup parent) {
|
||||
view = null;
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
view = inflater.inflate(R.layout.activity_list_item, parent, false);
|
||||
TextView timeFrom = view.findViewById(R.id.line_layout_time_from);
|
||||
TextView timeTo = view.findViewById(R.id.line_layout_time_to);
|
||||
TextView activityName = view.findViewById(R.id.line_layout_activity_name);
|
||||
@ -160,6 +175,9 @@ public abstract class AbstractActivityListingAdapter<T> extends ArrayAdapter<T>
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
protected abstract View fill_dashboard(T item, int position, View view, ViewGroup parent, Context context);
|
||||
|
||||
protected abstract String getDateLabel(T item);
|
||||
|
||||
protected abstract boolean hasGPS(T item);
|
||||
@ -182,6 +200,8 @@ public abstract class AbstractActivityListingAdapter<T> extends ArrayAdapter<T>
|
||||
|
||||
protected abstract String getDurationLabel(T item);
|
||||
|
||||
protected abstract String getSessionCountLabel(T item);
|
||||
|
||||
protected abstract boolean hasHR(T item);
|
||||
|
||||
protected abstract boolean hasIntensity(T item);
|
||||
@ -190,6 +210,14 @@ public abstract class AbstractActivityListingAdapter<T> extends ArrayAdapter<T>
|
||||
|
||||
protected abstract boolean hasSteps(T item);
|
||||
|
||||
protected abstract boolean hasTotalSteps(T item);
|
||||
|
||||
protected abstract boolean isSummary(T item);
|
||||
|
||||
protected abstract boolean isEmptySummary(T item);
|
||||
|
||||
protected abstract String getStepTotalLabel(T item);
|
||||
|
||||
public void setZebraStripes(boolean enable) {
|
||||
zebraStripes = enable;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ package nodomain.freeyourgadget.gadgetbridge.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.format.DateUtils;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Calendar;
|
||||
@ -134,6 +136,11 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
|
||||
this.deviceFilter = device;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View fill_dashboard(BaseActivitySummary item, int position, View view, ViewGroup parent, Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDateLabel(BaseActivitySummary item) {
|
||||
Date startTime = item.getStartTime();
|
||||
@ -219,6 +226,11 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
|
||||
return DateTimeUtils.formatDurationHoursMinutes(duration, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSessionCountLabel(BaseActivitySummary item) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasHR(BaseActivitySummary item) {
|
||||
return false;
|
||||
@ -239,6 +251,26 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasTotalSteps(BaseActivitySummary item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSummary(BaseActivitySummary item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEmptySummary(BaseActivitySummary item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStepTotalLabel(BaseActivitySummary item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getIcon(BaseActivitySummary item) {
|
||||
return ActivityKind.getIconId(item.getActivityKind());
|
||||
|
@ -0,0 +1,98 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
// ActivitySession holds activities detected by the steps/hr/intensity
|
||||
// and is used in the Activity List
|
||||
public class ActivitySession {
|
||||
|
||||
public static int SESSION_NORMAL = 1;
|
||||
public static int SESSION_SUMMARY = 2;
|
||||
|
||||
private final Date startTime;
|
||||
private final Date endTime;
|
||||
private final int activeSteps;
|
||||
private final int heartRateAverage;
|
||||
private final float intensity;
|
||||
private final float distance;
|
||||
private final int activityKind;
|
||||
// following is related to step session, we hold it here for the listview
|
||||
// it is identified by SESSION_SUMMARY
|
||||
private int sessionCount = 0;
|
||||
private int sessionType = SESSION_NORMAL;
|
||||
private boolean isEmptySummary = false; // in case there is no activity on that day
|
||||
private int totalDaySteps;
|
||||
|
||||
|
||||
public ActivitySession(Date startTime,
|
||||
Date endTime,
|
||||
int steps, int heartRateAverage, float intensity, float distance, int activityKind) {
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
this.activeSteps = steps;
|
||||
this.heartRateAverage = heartRateAverage;
|
||||
this.intensity = intensity;
|
||||
this.distance = distance;
|
||||
this.activityKind = activityKind;
|
||||
}
|
||||
|
||||
public Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public Date getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public int getActiveSteps() {
|
||||
return activeSteps;
|
||||
}
|
||||
|
||||
public int getHeartRateAverage() {
|
||||
return heartRateAverage;
|
||||
}
|
||||
|
||||
public int getActivityKind() {
|
||||
return activityKind;
|
||||
}
|
||||
|
||||
public float getIntensity() {
|
||||
return intensity;
|
||||
}
|
||||
|
||||
public float getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public int getSessionCount() {
|
||||
return sessionCount;
|
||||
}
|
||||
|
||||
public void setSessionCount(int sessionCount) {
|
||||
this.sessionCount = sessionCount;
|
||||
}
|
||||
|
||||
public int getSessionType() {
|
||||
return sessionType;
|
||||
}
|
||||
|
||||
public void setSessionType(int sessionType) {
|
||||
this.sessionType = sessionType;
|
||||
}
|
||||
|
||||
public boolean getIsEmptySummary() {
|
||||
return isEmptySummary;
|
||||
}
|
||||
|
||||
public void setEmptySummary(boolean emptySummary) {
|
||||
this.isEmptySummary = emptySummary;
|
||||
}
|
||||
|
||||
public int getTotalDaySteps() {
|
||||
return totalDaySteps;
|
||||
}
|
||||
|
||||
public void setTotalDaySteps(int totalDaySteps) {
|
||||
this.totalDaySteps = totalDaySteps;
|
||||
}
|
||||
}
|
31
app/src/main/res/drawable/ic_activity_stacked.xml
Normal file
31
app/src/main/res/drawable/ic_activity_stacked.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="26dp"
|
||||
android:height="26dp"
|
||||
android:tint="#7E7E7E"
|
||||
android:viewportWidth="26"
|
||||
android:viewportHeight="26">
|
||||
<path
|
||||
android:pathData="m11.711,16.3278a4.8542,7.133 75.8015,0 1,-5.6028 -5.0206,4.8542 7.133,75.8015 0,1 8.1903,-5.0206 4.8542,7.133 75.8015,0 1,5.6028 5.0206,4.8542 7.133,75.8015 0,1 -8.1903,5.0206M21.4865,14.0769 L26.0048,11.3072 22.914,8.5375L23.9253,4.613L18.5345,4.613L15.4436,1.8433 10.9253,4.613L5.5345,4.613L4.5232,8.5375L0.0048,11.3072 3.0957,14.0769L2.0844,18.0013L7.4752,18.0013L10.566,20.771 15.0844,18.0013L20.4752,18.0013Z"
|
||||
android:strokeWidth="1.01966"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="m4.273,11.6324l4.094,0l3.4795,-4.2078 1.0371,4.5933 2.6841,-2.2817l7.4587,0l-0.8601,1.1607L16.1168,10.897l-4.3503,3.7731 -0.8612,-3.8037 -1.6109,2.011 -4.0304,-0.0003z"
|
||||
android:strokeWidth="1.01966"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="m1.8709,18.7471l-0.3147,1.2211l5.343,0l3.129,2.807 4.5735,-2.807l5.3453,0l0.3147,-1.2211l-5.4373,0l-4.4626,2.734 -3.0558,-2.734z"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.591009"
|
||||
android:fillColor="#000000"
|
||||
android:strokeColor="#00000000"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeLineCap="butt"/>
|
||||
<path
|
||||
android:pathData="m1.367,20.7367l-0.3147,1.2211l5.3453,0l3.1268,2.807 4.5735,-2.807l5.3453,0l0.3147,-1.2211l-5.4373,0l-4.4626,2.734 -3.0535,-2.734z"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.591009"
|
||||
android:fillColor="#000000"
|
||||
android:strokeColor="#00000000"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeLineCap="butt"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_filter_none.xml
Normal file
10
app/src/main/res/drawable/ic_filter_none.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M3,5L1,5v16c0,1.1 0.9,2 2,2h16v-2L3,21L3,5zM21,1L7,1c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L23,3c0,-1.1 -0.9,-2 -2,-2zM21,17L7,17L7,3h14v14z"/>
|
||||
</vector>
|
11
app/src/main/res/drawable/ic_functions.xml
Normal file
11
app/src/main/res/drawable/ic_functions.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#7E7E7E"
|
||||
>
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M18,4H6v2l6.5,6L6,18v2h12v-3h-7l5,-5 -5,-5h7V4z"/>
|
||||
</vector>
|
@ -1,15 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="21.367056dp"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#7E7E7E"
|
||||
android:viewportWidth="21.367056"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="m2.5,15.5784h4.1775L8.9012,9.8743 11.3875,16.1187 13.8885,6.0045 18.8671,15.5784 18.7123,18.896 14.4568,10.4989 11.965,21.5 8.9404,14.1173 7.9512,17.3235 3.8385,17.323Z"
|
||||
android:strokeWidth="0.999994" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M8.9696,4.2276C9.4586,4.1648 9.801,3.7264 9.7306,3.2534 9.6601,2.7804 9.2023,2.4448 8.7133,2.5076 8.2243,2.5704 7.8819,3.0088 7.9524,3.4818 8.0229,3.9548 8.4806,4.2904 8.9696,4.2276ZM8.4469,10.4135 L8.5536,8.4877 10.1225,8.8668 10.2231,10.2646 11.2606,10.2284 11.0342,8.158 9.2155,7.7021 9.29,6.3777C9.964,6.9486 10.9171,7.2644 11.8951,7.1388L11.767,6.2788C10.9224,6.3872 10.147,6.0486 9.7017,5.4922L9.1546,4.8612C8.9384,4.6261 8.646,4.4883 8.3348,4.5283 8.2015,4.5454 8.119,4.5998 7.9856,4.617L5.8149,5.8599 6.1161,7.881 7.0052,7.7668 6.7873,6.3047 7.5427,5.9009 7.3579,9.9383l-1.3898,1.6275 0.4224,0.9079z"
|
||||
android:strokeWidth="1" />
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M11.57,13.16c-1.36,0.28 -2.17,1.16 -2.17,2.41 0,1.34 1.11,2.42 2.49,2.42 2.05,0 3.71,-1.66 3.71,-3.71 0,-1.07 -0.15,-2.12 -0.46,-3.12 -0.79,1.07 -2.2,1.72 -3.57,2zM13.5,0.67s0.74,2.65 0.74,4.8c0,2.06 -1.35,3.73 -3.41,3.73 -2.07,0 -3.63,-1.67 -3.63,-3.73l0.03,-0.36C5.21,7.51 4,10.62 4,14c0,4.42 3.58,8 8,8s8,-3.58 8,-8C20,8.61 17.41,3.8 13.5,0.67zM12,20c-3.31,0 -6,-2.69 -6,-6 0,-1.53 0.3,-3.04 0.86,-4.43 1.01,1.01 2.41,1.63 3.97,1.63 2.66,0 4.75,-1.83 5.28,-4.43C17.34,8.97 18,11.44 18,14c0,3.31 -2.69,6 -6,6z" />
|
||||
</vector>
|
||||
|
10
app/src/main/res/drawable/ic_intensity_hollow.xml
Normal file
10
app/src/main/res/drawable/ic_intensity_hollow.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:tint="#7E7E7E"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="m13.5,0.67c0,0 0.74,2.65 0.74,4.8 0,2.06 -1.35,3.73 -3.41,3.73C8.76,9.2 7.2,7.53 7.2,5.47L7.23,5.11C5.21,7.51 4,10.62 4,14c0,4.42 3.58,8 8,8 4.42,0 8,-3.58 8,-8C20,8.61 17.41,3.8 13.5,0.67ZM12,20C8.69,20 6,17.31 6,14 6,12.47 6.3,10.96 6.86,9.57c1.01,1.01 2.41,1.63 3.97,1.63 2.66,0 4.75,-1.83 5.28,-4.43 1.23,2.2 1.89,4.67 1.89,7.23 0,3.31 -2.69,6 -6,6z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_shoe_print.xml
Normal file
10
app/src/main/res/drawable/ic_shoe_print.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:tint="#7E7E7E"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M10.74,11.72C11.21,12.95 11.16,14.23 9.75,14.74C6.85,15.81 6.2,13 6.16,12.86L10.74,11.72M5.71,10.91L10.03,9.84C9.84,8.79 10.13,7.74 10.13,6.5C10.13,4.82 8.8,1.53 6.68,2.06C4.26,2.66 3.91,5.35 4,6.65C4.12,7.95 5.64,10.73 5.71,10.91M17.85,19.85C17.82,20 17.16,22.8 14.26,21.74C12.86,21.22 12.8,19.94 13.27,18.71L17.85,19.85M20,13.65C20.1,12.35 19.76,9.65 17.33,9.05C15.22,8.5 13.89,11.81 13.89,13.5C13.89,14.73 14.17,15.78 14,16.83L18.3,17.9C18.38,17.72 19.89,14.94 20,13.65Z" />
|
||||
</vector>
|
15
app/src/main/res/drawable/ic_shoe_prints_many.xml
Normal file
15
app/src/main/res/drawable/ic_shoe_prints_many.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:tint="#7E7E7E"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="m6.4801,14.3793c0.3823,1.0311 0.3416,2.104 -0.8053,2.5316C3.3159,17.8078 2.7872,15.4522 2.7547,15.3349l3.7255,-0.9556M2.3886,13.7003 L5.9026,12.8033c-0.1546,-0.8802 0.0813,-1.7604 0.0813,-2.7998 0,-1.4083 -1.0819,-4.1662 -2.8063,-3.7219 -1.9685,0.503 -2.2532,2.7579 -2.18,3.8476 0.0976,1.0897 1.334,3.4201 1.391,3.571m9.8749,7.4941C12.2392,21.3201 11.7023,23.6672 9.3434,22.7787 8.2046,22.3428 8.1558,21.2698 8.5381,20.2387l3.7255,0.9556m1.7489,-5.1972c0.0813,-1.0897 -0.1952,-3.3531 -2.1718,-3.856 -1.7163,-0.461 -2.7982,2.3136 -2.7982,3.7303 0,1.0311 0.2278,1.9112 0.0895,2.7914l3.4977,0.8969c0.0651,-0.1509 1.2933,-2.4813 1.3828,-3.5626z"
|
||||
android:strokeWidth="0.999999"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M14.7308,7.4903C14.986,8.2348 14.9589,9.0096 14.1934,9.3183 12.6189,9.9659 12.266,8.2651 12.2443,8.1803L14.7308,7.4903M12,7 L14.3454,6.3523c-0.1032,-0.6356 0.0543,-1.2711 0.0543,-2.0217 0,-1.0169 -0.7221,-3.0083 -1.873,-2.6875 -1.3138,0.3632 -1.5039,1.9914 -1.455,2.7783C11.1368,5.2083 11.962,6.891 12,7m6.5909,5.4113c-0.0162,0.0908 -0.3746,1.7856 -1.949,1.144 -0.7601,-0.3148 -0.7926,-1.0895 -0.5375,-1.834l2.4865,0.69m1.1673,-3.7528c0.0543,-0.7869 -0.1303,-2.4212 -1.4496,-2.7843 -1.1455,-0.3329 -1.8676,1.6706 -1.8676,2.6935 0,0.7445 0.152,1.3801 0.0597,2.0156l2.3345,0.6477c0.0435,-0.109 0.8632,-1.7917 0.9229,-2.5725z"
|
||||
android:strokeWidth="0.999998"/>
|
||||
</vector>
|
379
app/src/main/res/layout/activity_list_dashboard_item.xml
Normal file
379
app/src/main/res/layout/activity_list_dashboard_item.xml
Normal file
@ -0,0 +1,379 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/list_item_parent_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<!--
|
||||
android:background="?android:attr/activatedBackgroundIndicator"
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.github.mikephil.charting.charts.PieChart
|
||||
android:id="@+id/activity_dashboard_piechart1"
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="110dp"
|
||||
android:layout_gravity="bottom|center"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<com.github.mikephil.charting.charts.PieChart
|
||||
android:id="@+id/activity_dashboard_piechart2"
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="110dp"
|
||||
android:layout_gravity="bottom|center"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<com.github.mikephil.charting.charts.PieChart
|
||||
android:id="@+id/activity_dashboard_piechart3"
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="110dp"
|
||||
android:layout_gravity="bottom|center"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_weight="1" />
|
||||
<!--
|
||||
<com.github.mikephil.charting.charts.PieChart
|
||||
android:id="@+id/activity_dashboard_piechart4"
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_gravity="bottom|center"
|
||||
android:layout_marginBottom="0dp" />
|
||||
-->
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<View
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="0.5" />
|
||||
|
||||
<include
|
||||
layout="@layout/heartrate_average_widget"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_gravity="bottom|center"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<include
|
||||
layout="@layout/intensity_total_widget"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_gravity="bottom|center"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="0.5" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="bottom|center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/line_layout_step"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|top"
|
||||
android:layout_marginStart="1dp"
|
||||
android:layout_marginEnd="1dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center|top"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/line_layout_step_icon"
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/candidate_item_device_image"
|
||||
app:srcCompat="@drawable/ic_shoe_print" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_step_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="@string/activity_list_summary_active_steps" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_step_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:fontFamily="sans-serif-black"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="15000" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/line_layout_distance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|top"
|
||||
android:layout_marginStart="1dp"
|
||||
android:layout_marginEnd="1dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center|top"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/line_layout_distance_icon"
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/candidate_item_device_image"
|
||||
app:srcCompat="@drawable/ic_distance" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_distance_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="@string/distance" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_distance_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:fontFamily="sans-serif-black"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="15.1km" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/line_layout_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|top"
|
||||
android:layout_marginStart="1dp"
|
||||
android:layout_marginEnd="1dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center|top"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/line_layout_duration_icon"
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/candidate_item_device_image"
|
||||
app:srcCompat="@drawable/ic_access_time" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_duration_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="@string/activity_list_summary_active_time" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_duration_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:fontFamily="sans-serif-black"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="122" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/line_layout_total_step"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|top"
|
||||
android:layout_marginStart="1dp"
|
||||
android:layout_marginEnd="1dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/line_layout_total_step_icon"
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/candidate_item_device_image"
|
||||
app:srcCompat="@drawable/ic_shoe_prints_many" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_total_step_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="@string/live_activity_total_steps" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_total_step_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:fontFamily="sans-serif-black"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="15000" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/line_layout_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|top"
|
||||
android:layout_marginStart="1dp"
|
||||
android:layout_marginEnd="1dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/line_layout_count_icon"
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/candidate_item_device_image"
|
||||
app:srcCompat="@drawable/ic_activity_stacked" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_count_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="@string/activity_list_summary_activities" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_count_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:fontFamily="sans-serif-black"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="15" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/line_layout_intensity2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center"
|
||||
android:layout_marginStart="1dp"
|
||||
android:layout_marginEnd="1dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="bottom|center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/line_layout_intensity2_icon"
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/candidate_item_device_image"
|
||||
app:srcCompat="@drawable/ic_intensity" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_intensity2_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="@string/activity_list_summary_intensity" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_intensity2_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:fontFamily="sans-serif-black"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="false"
|
||||
android:text="15" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
@ -134,7 +134,7 @@
|
||||
android:layout_height="19dp"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:contentDescription="@string/candidate_item_device_image"
|
||||
app:srcCompat="@drawable/ic_shoe" />
|
||||
app:srcCompat="@drawable/ic_shoe_print" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/line_layout_step_label"
|
||||
|
@ -4,7 +4,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stepsDateView"
|
||||
android:layout_width="match_parent"
|
||||
@ -14,8 +13,12 @@
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
||||
|
||||
<ListView
|
||||
android:id="@+id/itemListView"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -14,14 +14,13 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_activity_unknown" />
|
||||
app:srcCompat="@drawable/ic_intensity_hollow" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/intensity_widget_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="3dp"
|
||||
android:paddingEnd="3dp"
|
||||
android:paddingTop="10dp"
|
||||
android:text=""
|
||||
android:textAlignment="center"
|
||||
android:textSize="12sp"
|
||||
|
@ -443,6 +443,11 @@
|
||||
<string name="weekstepschart_steps_a_week">Steps per week</string>
|
||||
<string name="activity_sleepchart_activity_and_sleep">Activity</string>
|
||||
<string name="charts_activity_list">Activity list</string>
|
||||
<string name="activity_list_summary_active_steps">Active steps</string>
|
||||
<string name="activity_list_summary_distance">Distance</string>
|
||||
<string name="activity_list_summary_active_time">Active time</string>
|
||||
<string name="activity_list_summary_intensity">Movement\nIntensity</string>
|
||||
<string name="activity_list_summary_activities">Activities</string>
|
||||
<string name="lack_of_sleep">Lack of sleep: %1$s</string>
|
||||
<string name="overslept">Overslept: %1$s</string>
|
||||
<!-- Firmware updating -->
|
||||
|
Loading…
Reference in New Issue
Block a user