mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-23 16:53:04 +02:00
polynomical order can now be set for the regression weight line
This commit is contained in:
@@ -0,0 +1,215 @@
|
|||||||
|
package com.health.openscale.core.utils;
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Paul Lutus, Ian Clarke *
|
||||||
|
* lutusp@arachnoid.com, ian.clarke@gmail.com *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to fit a polynomial to a (potentially very large) dataset.
|
||||||
|
*
|
||||||
|
* @author Paul Lutus <lutusp@arachnoid.com>
|
||||||
|
* @author Ian Clarke <ian.clarke@gmail.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Changelog:
|
||||||
|
* 20100130: Add note about relicensing
|
||||||
|
* 20091114: Modify so that points can be added after the curve is
|
||||||
|
* created, also some other minor fixes
|
||||||
|
* 20091113: Extensively modified by Ian Clarke, main changes:
|
||||||
|
* - Should now be able to handle extremely large datasets
|
||||||
|
* - Use generic Java collections classes and interfaces
|
||||||
|
* where possible
|
||||||
|
* - Data can be fed to the fitter as it is available, rather
|
||||||
|
* than all at once
|
||||||
|
*
|
||||||
|
* The code that this is based on was obtained from: http://arachnoid.com/polysolve
|
||||||
|
*
|
||||||
|
* Note: I (Ian Clarke) am happy to release this code under a more liberal
|
||||||
|
* license such as the LGPL, however Paul Lutus (the primary author) refuses
|
||||||
|
* to do this on the grounds that the LGPL is not an open source license.
|
||||||
|
* If you want to try to explain to him that the LGPL is indeed an open
|
||||||
|
* source license, good luck - it's like talking to a brick wall.
|
||||||
|
*/
|
||||||
|
public class PolynomialFitter {
|
||||||
|
|
||||||
|
private final int p, rs;
|
||||||
|
|
||||||
|
private long n = 0;
|
||||||
|
|
||||||
|
private final double[][] m;
|
||||||
|
|
||||||
|
private final double[] mpc;
|
||||||
|
/**
|
||||||
|
* @param degree
|
||||||
|
* The degree of the polynomial to be fit to the data
|
||||||
|
*/
|
||||||
|
public PolynomialFitter(final int degree) {
|
||||||
|
assert degree > 0;
|
||||||
|
p = degree + 1;
|
||||||
|
rs = 2 * p - 1;
|
||||||
|
m = new double[p][p + 1];
|
||||||
|
mpc = new double[rs];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a point to the set of points that the polynomial must be fit to
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* The x coordinate of the point
|
||||||
|
* @param y
|
||||||
|
* The y coordinate of the point
|
||||||
|
*/
|
||||||
|
public void addPoint(final double x, final double y) {
|
||||||
|
assert !Double.isInfinite(x) && !Double.isNaN(x);
|
||||||
|
assert !Double.isInfinite(y) && !Double.isNaN(y);
|
||||||
|
n++;
|
||||||
|
// process precalculation array
|
||||||
|
for (int r = 1; r < rs; r++) {
|
||||||
|
mpc[r] += Math.pow(x, r);
|
||||||
|
}
|
||||||
|
// process RH column cells
|
||||||
|
m[0][p] += y;
|
||||||
|
for (int r = 1; r < p; r++) {
|
||||||
|
m[r][p] += Math.pow(x, r) * y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a polynomial that seeks to minimize the square of the total
|
||||||
|
* distance between the set of points and the polynomial.
|
||||||
|
*
|
||||||
|
* @return A polynomial
|
||||||
|
*/
|
||||||
|
public Polynomial getBestFit() {
|
||||||
|
final double[] mpcClone = mpc.clone();
|
||||||
|
final double[][] mClone = new double[m.length][];
|
||||||
|
for (int x = 0; x < mClone.length; x++) {
|
||||||
|
mClone[x] = m[x].clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
mpcClone[0] += n;
|
||||||
|
// populate square matrix section
|
||||||
|
for (int r = 0; r < p; r++) {
|
||||||
|
for (int c = 0; c < p; c++) {
|
||||||
|
mClone[r][c] = mpcClone[r + c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gj_echelonize(mClone);
|
||||||
|
final Polynomial result = new Polynomial(p);
|
||||||
|
for (int j = 0; j < p; j++) {
|
||||||
|
result.add(j, mClone[j][p]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private double fx(final double x, final List<Double> terms) {
|
||||||
|
double a = 0;
|
||||||
|
int e = 0;
|
||||||
|
for (final double i : terms) {
|
||||||
|
a += i * Math.pow(x, e);
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
private void gj_divide(final double[][] A, final int i, final int j, final int m) {
|
||||||
|
for (int q = j + 1; q < m; q++) {
|
||||||
|
A[i][q] /= A[i][j];
|
||||||
|
}
|
||||||
|
A[i][j] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void gj_echelonize(final double[][] A) {
|
||||||
|
final int n = A.length;
|
||||||
|
final int m = A[0].length;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
while (i < n && j < m) {
|
||||||
|
// look for a non-zero entry in col j at or below row i
|
||||||
|
int k = i;
|
||||||
|
while (k < n && A[k][j] == 0) {
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
// if such an entry is found at row k
|
||||||
|
if (k < n) {
|
||||||
|
// if k is not i, then swap row i with row k
|
||||||
|
if (k != i) {
|
||||||
|
gj_swap(A, i, j);
|
||||||
|
}
|
||||||
|
// if A[i][j] is not 1, then divide row i by A[i][j]
|
||||||
|
if (A[i][j] != 1) {
|
||||||
|
gj_divide(A, i, j, m);
|
||||||
|
}
|
||||||
|
// eliminate all other non-zero entries from col j by
|
||||||
|
// subtracting from each
|
||||||
|
// row (other than i) an appropriate multiple of row i
|
||||||
|
gj_eliminate(A, i, j, n, m);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void gj_eliminate(final double[][] A, final int i, final int j, final int n, final int m) {
|
||||||
|
for (int k = 0; k < n; k++) {
|
||||||
|
if (k != i && A[k][j] != 0) {
|
||||||
|
for (int q = j + 1; q < m; q++) {
|
||||||
|
A[k][q] -= A[k][j] * A[i][q];
|
||||||
|
}
|
||||||
|
A[k][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void gj_swap(final double[][] A, final int i, final int j) {
|
||||||
|
double temp[];
|
||||||
|
temp = A[i];
|
||||||
|
A[i] = A[j];
|
||||||
|
A[j] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class Polynomial extends ArrayList<Double> {
|
||||||
|
private static final long serialVersionUID = 1692843494322684190L;
|
||||||
|
|
||||||
|
public Polynomial(final int p) {
|
||||||
|
super(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getY(final double x) {
|
||||||
|
double ret = 0;
|
||||||
|
for (int p=0; p<size(); p++) {
|
||||||
|
ret += get(p)*(Math.pow(x, p));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder ret = new StringBuilder();
|
||||||
|
for (int x = size() - 1; x > -1; x--) {
|
||||||
|
ret.append(get(x) + (x > 0 ? "x^" + x + " + " : ""));
|
||||||
|
}
|
||||||
|
return ret.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -36,6 +36,7 @@ import android.widget.TextView;
|
|||||||
import com.health.openscale.R;
|
import com.health.openscale.R;
|
||||||
import com.health.openscale.core.OpenScale;
|
import com.health.openscale.core.OpenScale;
|
||||||
import com.health.openscale.core.datatypes.ScaleData;
|
import com.health.openscale.core.datatypes.ScaleData;
|
||||||
|
import com.health.openscale.core.utils.PolynomialFitter;
|
||||||
import com.health.openscale.gui.activities.DataEntryActivity;
|
import com.health.openscale.gui.activities.DataEntryActivity;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -284,7 +285,6 @@ public class GraphFragment extends Fragment implements FragmentUpdateListener {
|
|||||||
setHasPoints(prefs.getBoolean("pointsEnable", true)).
|
setHasPoints(prefs.getBoolean("pointsEnable", true)).
|
||||||
setFormatter(new SimpleLineChartValueFormatter(1));
|
setFormatter(new SimpleLineChartValueFormatter(1));
|
||||||
|
|
||||||
|
|
||||||
if(prefs.getBoolean("weightEnable", true) && prefs.getBoolean(String.valueOf(diagramWeight.getId()), true)) {
|
if(prefs.getBoolean("weightEnable", true) && prefs.getBoolean(String.valueOf(diagramWeight.getId()), true)) {
|
||||||
lines.add(lineWeight);
|
lines.add(lineWeight);
|
||||||
diagramWeight.setBackgroundTintList(ColorStateList.valueOf(ChartUtils.COLOR_VIOLET));
|
diagramWeight.setBackgroundTintList(ColorStateList.valueOf(ChartUtils.COLOR_VIOLET));
|
||||||
@@ -333,6 +333,22 @@ public class GraphFragment extends Fragment implements FragmentUpdateListener {
|
|||||||
enableMonth.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#d3d3d3")));
|
enableMonth.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#d3d3d3")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LineChartData lineData = new LineChartData(lines);
|
||||||
|
lineData.setAxisXBottom(new Axis(axisValues).
|
||||||
|
setHasLines(true).
|
||||||
|
setTextColor(Color.BLACK)
|
||||||
|
);
|
||||||
|
|
||||||
|
lineData.setAxisYLeft(new Axis().
|
||||||
|
setHasLines(true).
|
||||||
|
setMaxLabelChars(5).
|
||||||
|
setTextColor(Color.BLACK)
|
||||||
|
);
|
||||||
|
|
||||||
|
chartBottom.setLineChartData(lineData);
|
||||||
|
|
||||||
|
defaultTopViewport = new Viewport(0, chartBottom.getCurrentViewport().top+4, axisValues.size()-1, chartBottom.getCurrentViewport().bottom-4);
|
||||||
|
|
||||||
if (prefs.getBoolean("goalLine", true)) {
|
if (prefs.getBoolean("goalLine", true)) {
|
||||||
Stack<PointValue> valuesGoalLine = new Stack<PointValue>();
|
Stack<PointValue> valuesGoalLine = new Stack<PointValue>();
|
||||||
|
|
||||||
@@ -349,112 +365,23 @@ public class GraphFragment extends Fragment implements FragmentUpdateListener {
|
|||||||
lines.add(goalLine);
|
lines.add(goalLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefs.getBoolean("regressionLine", true)) {
|
if (prefs.getBoolean("regressionLine", false)) {
|
||||||
|
PolynomialFitter polyFitter = new PolynomialFitter(Integer.parseInt(prefs.getString("regressionLineOrder", "1")));
|
||||||
|
|
||||||
/*
|
for(PointValue weightValue : valuesWeight) {
|
||||||
// quadratic regression y = ax^2 + bx + c
|
polyFitter.addPoint(weightValue.getX(), weightValue.getY());
|
||||||
double x_value = 0.0;
|
|
||||||
double y_value = 0.0;
|
|
||||||
|
|
||||||
double s40 = 0; //sum of x^4
|
|
||||||
double s30 = 0; //sum of x^3
|
|
||||||
double s20 = 0; //sum of x^2
|
|
||||||
double s10 = 0; //sum of x
|
|
||||||
double s00 = scaleDataList.size();
|
|
||||||
//sum of x^0 * y^0 ie 1 * number of entries
|
|
||||||
|
|
||||||
double s21 = 0; //sum of x^2*y
|
|
||||||
double s11 = 0; //sum of x*y
|
|
||||||
double s01 = 0; //sum of y
|
|
||||||
|
|
||||||
for(ScaleData scaleEntry: scaleDataList) {
|
|
||||||
calDB.setTime(scaleEntry.getDateTime());
|
|
||||||
|
|
||||||
x_value = calDB.get(field);
|
|
||||||
y_value = scaleEntry.getConvertedWeight(openScale.getSelectedScaleUser().scale_unit);
|
|
||||||
|
|
||||||
s40 += Math.pow(x_value, 4);
|
|
||||||
s30 += Math.pow(x_value, 3);
|
|
||||||
s20 += Math.pow(x_value, 2);
|
|
||||||
s10 += x_value;
|
|
||||||
|
|
||||||
s21 += Math.pow(x_value, 2) * y_value;
|
|
||||||
s11 += x_value * y_value;
|
|
||||||
s01 += y_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// solve equations using Cramer's law
|
PolynomialFitter.Polynomial polynom = polyFitter.getBestFit();
|
||||||
double a = (s21*(s20 * s00 - s10 * s10) -
|
|
||||||
s11*(s30 * s00 - s10 * s20) +
|
|
||||||
s01*(s30 * s10 - s20 * s20))
|
|
||||||
/
|
|
||||||
(s40*(s20 * s00 - s10 * s10) -
|
|
||||||
s30*(s30 * s00 - s10 * s20) +
|
|
||||||
s20*(s30 * s10 - s20 * s20));
|
|
||||||
|
|
||||||
double b = (s40*(s11 * s00 - s01 * s10) -
|
|
||||||
s30*(s21 * s00 - s01 * s20) +
|
|
||||||
s20*(s21 * s10 - s11 * s20))
|
|
||||||
/
|
|
||||||
(s40 * (s20 * s00 - s10 * s10) -
|
|
||||||
s30 * (s30 * s00 - s10 * s20) +
|
|
||||||
s20 * (s30 * s10 - s20 * s20));
|
|
||||||
|
|
||||||
double c = (s40*(s20 * s01 - s10 * s11) -
|
|
||||||
s30*(s30 * s01 - s10 * s21) +
|
|
||||||
s20*(s30 * s11 - s20 * s21))
|
|
||||||
/
|
|
||||||
(s40 * (s20 * s00 - s10 * s10) -
|
|
||||||
s30 * (s30 * s00 - s10 * s20) +
|
|
||||||
s20 * (s30 * s10 - s20 * s20));
|
|
||||||
*/
|
|
||||||
|
|
||||||
// linear regression y = a + x*b
|
|
||||||
double sumx = 0.0;
|
|
||||||
double sumy = 0.0;
|
|
||||||
|
|
||||||
double x_value = 0.0;
|
|
||||||
double y_value = 0.0;
|
|
||||||
|
|
||||||
for(ScaleData scaleEntry: scaleDataList) {
|
|
||||||
calDB.setTime(scaleEntry.getDateTime());
|
|
||||||
|
|
||||||
x_value = calDB.get(field);
|
|
||||||
y_value = scaleEntry.getConvertedWeight(openScale.getSelectedScaleUser().scale_unit);
|
|
||||||
|
|
||||||
sumx += x_value;
|
|
||||||
sumy += y_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double xbar = sumx / scaleDataList.size();
|
|
||||||
double ybar = sumy / scaleDataList.size();
|
|
||||||
|
|
||||||
double xxbar = 0.0;
|
|
||||||
double xybar = 0.0;
|
|
||||||
|
|
||||||
for(ScaleData scaleEntry: scaleDataList) {
|
|
||||||
calDB.setTime(scaleEntry.getDateTime());
|
|
||||||
|
|
||||||
x_value = calDB.get(field);
|
|
||||||
y_value = scaleEntry.getConvertedWeight(openScale.getSelectedScaleUser().scale_unit);
|
|
||||||
|
|
||||||
xxbar += (x_value - xbar) * (x_value - xbar);
|
|
||||||
xybar += (y_value - xbar) * (y_value - ybar);
|
|
||||||
}
|
|
||||||
|
|
||||||
double b = xybar / xxbar;
|
|
||||||
double a = ybar - b * xbar;
|
|
||||||
|
|
||||||
|
|
||||||
Stack<PointValue> valuesLinearRegression = new Stack<PointValue>();
|
Stack<PointValue> valuesLinearRegression = new Stack<PointValue>();
|
||||||
|
|
||||||
for (int i = 0; i < 31; i++) {
|
if (!valuesWeight.isEmpty()) {
|
||||||
y_value = a + b * i; // linear regression
|
for (int i = (int)valuesWeight.peek().getX(); i <= 31; i++) {
|
||||||
//y_value = a * i*i + b * i + c; // quadratic regression
|
double y_value = polynom.getY(i);
|
||||||
|
valuesLinearRegression.push(new PointValue((float) i, (float) y_value));
|
||||||
valuesLinearRegression.push(new PointValue((float) i, (float) y_value));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Line linearRegressionLine = new Line(valuesLinearRegression)
|
Line linearRegressionLine = new Line(valuesLinearRegression)
|
||||||
.setColor(ChartUtils.COLOR_VIOLET)
|
.setColor(ChartUtils.COLOR_VIOLET)
|
||||||
.setHasPoints(false);
|
.setHasPoints(false);
|
||||||
@@ -464,22 +391,8 @@ public class GraphFragment extends Fragment implements FragmentUpdateListener {
|
|||||||
lines.add(linearRegressionLine);
|
lines.add(linearRegressionLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
LineChartData lineData = new LineChartData(lines);
|
|
||||||
lineData.setAxisXBottom(new Axis(axisValues).
|
|
||||||
setHasLines(true).
|
|
||||||
setTextColor(Color.BLACK)
|
|
||||||
);
|
|
||||||
|
|
||||||
lineData.setAxisYLeft(new Axis().
|
|
||||||
setHasLines(true).
|
|
||||||
setMaxLabelChars(5).
|
|
||||||
setTextColor(Color.BLACK)
|
|
||||||
);
|
|
||||||
|
|
||||||
chartBottom.setLineChartData(lineData);
|
chartBottom.setLineChartData(lineData);
|
||||||
defaultTopViewport = new Viewport(0, chartBottom.getCurrentViewport().top+4, axisValues.size()-1, chartBottom.getCurrentViewport().bottom-4);
|
|
||||||
|
|
||||||
chartBottom.setMaximumViewport(defaultTopViewport);
|
|
||||||
chartBottom.setCurrentViewport(defaultTopViewport);
|
chartBottom.setCurrentViewport(defaultTopViewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,16 +15,132 @@
|
|||||||
*/
|
*/
|
||||||
package com.health.openscale.gui.preferences;
|
package com.health.openscale.gui.preferences;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.preference.CheckBoxPreference;
|
||||||
|
import android.preference.EditTextPreference;
|
||||||
|
import android.preference.ListPreference;
|
||||||
|
import android.preference.MultiSelectListPreference;
|
||||||
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
|
import android.preference.PreferenceGroup;
|
||||||
|
import android.text.method.DigitsKeyListener;
|
||||||
|
|
||||||
import com.health.openscale.R;
|
import com.health.openscale.R;
|
||||||
|
|
||||||
public class GraphPreferences extends PreferenceFragment {
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class GraphPreferences extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
|
public static final String PREFERENCE_KEY_REGRESSION_LINE = "regressionLine";
|
||||||
|
public static final String PREFERENCE_KEY_REGRESSION_LINE_ORDER = "regressionLineOrder";
|
||||||
|
|
||||||
|
private CheckBoxPreference regressionLine;
|
||||||
|
private EditTextPreference regressionLineOrder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.graph_preferences);
|
addPreferencesFromResource(R.xml.graph_preferences);
|
||||||
|
|
||||||
|
regressionLine = (CheckBoxPreference) findPreference(PREFERENCE_KEY_REGRESSION_LINE);
|
||||||
|
regressionLineOrder = (EditTextPreference) findPreference(PREFERENCE_KEY_REGRESSION_LINE_ORDER);
|
||||||
|
|
||||||
|
regressionLineOrder.getEditText().setKeyListener(new DigitsKeyListener());
|
||||||
|
|
||||||
|
updateGraphPreferences();
|
||||||
|
initSummary(getPreferenceScreen());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume()
|
||||||
|
{
|
||||||
|
super.onResume();
|
||||||
|
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause()
|
||||||
|
{
|
||||||
|
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
|
||||||
|
{
|
||||||
|
updatePrefSummary(findPreference(key));
|
||||||
|
updateGraphPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSummary(Preference p)
|
||||||
|
{
|
||||||
|
if (p instanceof PreferenceGroup)
|
||||||
|
{
|
||||||
|
PreferenceGroup pGrp = (PreferenceGroup) p;
|
||||||
|
for (int i = 0; i < pGrp.getPreferenceCount(); i++)
|
||||||
|
{
|
||||||
|
initSummary(pGrp.getPreference(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updatePrefSummary(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateGraphPreferences()
|
||||||
|
{
|
||||||
|
if (regressionLine.isChecked())
|
||||||
|
{
|
||||||
|
regressionLineOrder.setEnabled(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regressionLineOrder.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePrefSummary(Preference p)
|
||||||
|
{
|
||||||
|
if (p instanceof ListPreference)
|
||||||
|
{
|
||||||
|
ListPreference listPref = (ListPreference) p;
|
||||||
|
p.setSummary(listPref.getEntry());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p instanceof EditTextPreference)
|
||||||
|
{
|
||||||
|
EditTextPreference editTextPref = (EditTextPreference) p;
|
||||||
|
if (p.getTitle().toString().contains("assword"))
|
||||||
|
{
|
||||||
|
p.setSummary("******");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.setSummary(editTextPref.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p instanceof MultiSelectListPreference)
|
||||||
|
{
|
||||||
|
MultiSelectListPreference editMultiListPref = (MultiSelectListPreference) p;
|
||||||
|
|
||||||
|
CharSequence[] entries = editMultiListPref.getEntries();
|
||||||
|
CharSequence[] entryValues = editMultiListPref.getEntryValues();
|
||||||
|
List<String> currentEntries = new ArrayList<>();
|
||||||
|
Set<String> currentEntryValues = editMultiListPref.getValues();
|
||||||
|
|
||||||
|
for (int i = 0; i < entries.length; i++)
|
||||||
|
{
|
||||||
|
if (currentEntryValues.contains(entryValues[i].toString())) currentEntries.add(entries[i].toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setSummary(currentEntries.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -151,6 +151,7 @@
|
|||||||
<string name="label_initial_weight">Initial weight</string>
|
<string name="label_initial_weight">Initial weight</string>
|
||||||
<string name="label_average_data">Calculate average per day/month</string>
|
<string name="label_average_data">Calculate average per day/month</string>
|
||||||
<string name="label_regression_line">Regression weight line</string>
|
<string name="label_regression_line">Regression weight line</string>
|
||||||
|
<string name="label_regression_line_order">Regression order</string>
|
||||||
<string name="label_goal_line">Goal line</string>
|
<string name="label_goal_line">Goal line</string>
|
||||||
|
|
||||||
|
|
||||||
|
@@ -5,4 +5,6 @@
|
|||||||
<CheckBoxPreference android:title="@string/label_delete_confirmation" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="deleteConfirmationEnable" android:defaultValue="true" />
|
<CheckBoxPreference android:title="@string/label_delete_confirmation" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="deleteConfirmationEnable" android:defaultValue="true" />
|
||||||
<CheckBoxPreference android:title="@string/label_average_data" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="averageData" android:defaultValue="true" />
|
<CheckBoxPreference android:title="@string/label_average_data" android:summaryOn="@string/info_is_enable" android:summaryOff="@string/info_is_not_enable" android:key="averageData" android:defaultValue="true" />
|
||||||
<CheckBoxPreference android:title="@string/label_goal_line" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="goalLine" android:defaultValue="true" />
|
<CheckBoxPreference android:title="@string/label_goal_line" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="goalLine" android:defaultValue="true" />
|
||||||
<CheckBoxPreference android:title="@string/label_regression_line" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="regressionLine" android:defaultValue="true" /></PreferenceScreen>
|
<CheckBoxPreference android:title="@string/label_regression_line" android:summaryOn="@string/info_is_visible" android:summaryOff="@string/info_is_not_visible" android:key="regressionLine" android:defaultValue="false" />
|
||||||
|
<EditTextPreference android:title="@string/label_regression_line_order" android:key="regressionLineOrder" android:defaultValue="1" />
|
||||||
|
</PreferenceScreen>
|
Reference in New Issue
Block a user