mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-19 15:01:53 +02:00
- some optimization to speed the table view calculation
- added progress bar to table view
This commit is contained in:
@@ -85,8 +85,10 @@ import com.health.openscale.gui.preferences.UserSettingsFragment;
|
|||||||
import com.health.openscale.gui.slides.AppIntroActivity;
|
import com.health.openscale.gui.slides.AppIntroActivity;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -1069,4 +1071,32 @@ public class MainActivity extends AppCompatActivity
|
|||||||
connectToBluetooth();
|
connectToBluetooth();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Generate random dummy measurements - ONLY FOR TESTING PURPOSE
|
||||||
|
private void generateDummyMeasurements(int measurementCount) {
|
||||||
|
for (int i=0; i<measurementCount; i++) {
|
||||||
|
ScaleMeasurement scaleMeasurement = new ScaleMeasurement();
|
||||||
|
|
||||||
|
SimpleDateFormat dfDateTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss",Locale.getDefault());
|
||||||
|
int year = randBetween(2005, 2023);// Here you can set Range of years you need
|
||||||
|
int month = randBetween(0, 11);
|
||||||
|
int hour = randBetween(9, 22); //Hours will be displayed in between 9 to 22
|
||||||
|
int min = randBetween(0, 59);
|
||||||
|
int sec = randBetween(0, 59);
|
||||||
|
|
||||||
|
GregorianCalendar gc = new GregorianCalendar(year, month, 1);
|
||||||
|
int day = randBetween(1, gc.getActualMaximum(gc.DAY_OF_MONTH));
|
||||||
|
|
||||||
|
gc.set(year, month, day, hour, min,sec);
|
||||||
|
|
||||||
|
scaleMeasurement.setDateTime(gc.getTime());
|
||||||
|
scaleMeasurement.setWeight(randBetween(30, 140));
|
||||||
|
|
||||||
|
OpenScale.getInstance().addScaleMeasurement(scaleMeasurement, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int randBetween(int start, int end) {
|
||||||
|
return start + (int)Math.round(Math.random() * (end - start));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -426,7 +426,7 @@ public abstract class FloatMeasurementView extends MeasurementView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendDiffValue(SpannableStringBuilder text, boolean newLine) {
|
public void appendDiffValue(final SpannableStringBuilder text, boolean newLine, boolean isEvalOn) {
|
||||||
if (previousValue < 0.0f) {
|
if (previousValue < 0.0f) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -446,6 +446,8 @@ public abstract class FloatMeasurementView extends MeasurementView {
|
|||||||
color = Color.GRAY;
|
color = Color.GRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip evaluation to speed the calculation up (e.g. not needed for table view)
|
||||||
|
if (isEvalOn) {
|
||||||
// change color depending on if you are going towards or away from your weight goal
|
// change color depending on if you are going towards or away from your weight goal
|
||||||
if (this instanceof WeightMeasurementView) {
|
if (this instanceof WeightMeasurementView) {
|
||||||
if (diff > 0.0f) {
|
if (diff > 0.0f) {
|
||||||
@@ -473,6 +475,7 @@ public abstract class FloatMeasurementView extends MeasurementView {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newLine) {
|
if (newLine) {
|
||||||
text.append('\n');
|
text.append('\n');
|
||||||
@@ -490,6 +493,12 @@ public abstract class FloatMeasurementView extends MeasurementView {
|
|||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDiffValue(final SpannableStringBuilder text, boolean newLine) {
|
||||||
|
appendDiffValue(text, newLine, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isEditable() {
|
protected boolean isEditable() {
|
||||||
if (useAutoValue()) {
|
if (useAutoValue()) {
|
||||||
|
@@ -286,7 +286,8 @@ public abstract class MeasurementView extends TableLayout {
|
|||||||
|
|
||||||
public CharSequence getName() { return nameView.getText(); }
|
public CharSequence getName() { return nameView.getText(); }
|
||||||
public abstract String getValueAsString(boolean withUnit);
|
public abstract String getValueAsString(boolean withUnit);
|
||||||
public void appendDiffValue(SpannableStringBuilder builder, boolean newLine) { }
|
public void appendDiffValue(final SpannableStringBuilder builder, boolean newLine, boolean isEvalOn) { }
|
||||||
|
public void appendDiffValue(final SpannableStringBuilder builder, boolean newLine) { }
|
||||||
public Drawable getIcon() { return iconView.getDrawable(); }
|
public Drawable getIcon() { return iconView.getDrawable(); }
|
||||||
public int getIconResource() { return iconId; }
|
public int getIconResource() { return iconId; }
|
||||||
public void setBackgroundIconColor(int color) {
|
public void setBackgroundIconColor(int color) {
|
||||||
|
@@ -85,6 +85,9 @@ class OverviewAdapter extends RecyclerView.Adapter<OverviewAdapter.ViewHolder> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull OverviewAdapter.ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull OverviewAdapter.ViewHolder holder, int position) {
|
||||||
|
holder.measurementHighlightViews.removeAllViews();
|
||||||
|
holder.measurementViews.removeAllViews();
|
||||||
|
|
||||||
ScaleMeasurement scaleMeasurement = scaleMeasurementList.get(position);
|
ScaleMeasurement scaleMeasurement = scaleMeasurementList.get(position);
|
||||||
ScaleMeasurement prevScaleMeasurement;
|
ScaleMeasurement prevScaleMeasurement;
|
||||||
|
|
||||||
|
@@ -36,7 +36,6 @@ import com.health.openscale.gui.utils.ColorUtil;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class StickyHeaderTableView extends View implements NestedScrollingChild {
|
public class StickyHeaderTableView extends View implements NestedScrollingChild {
|
||||||
|
|
||||||
private final Paint paintStrokeRect = new Paint();
|
private final Paint paintStrokeRect = new Paint();
|
||||||
private final Paint paintHeaderCellFillRect = new Paint();
|
private final Paint paintHeaderCellFillRect = new Paint();
|
||||||
private final Paint paintContentCellFillRect = new Paint();
|
private final Paint paintContentCellFillRect = new Paint();
|
||||||
@@ -45,6 +44,9 @@ public class StickyHeaderTableView extends View implements NestedScrollingChild
|
|||||||
|
|
||||||
private final TextPaint paintHeaderText = new TextPaint();
|
private final TextPaint paintHeaderText = new TextPaint();
|
||||||
private final Rect textRectBounds = new Rect();
|
private final Rect textRectBounds = new Rect();
|
||||||
|
|
||||||
|
private int maxMeasure = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visible rect size of view which is displayed on screen
|
* Visible rect size of view which is displayed on screen
|
||||||
*/
|
*/
|
||||||
@@ -483,11 +485,16 @@ public class StickyHeaderTableView extends View implements NestedScrollingChild
|
|||||||
* Required for onMeasure() method
|
* Required for onMeasure() method
|
||||||
*/
|
*/
|
||||||
private void updateMaxWidthHeightOfCell() {
|
private void updateMaxWidthHeightOfCell() {
|
||||||
|
// call only once otherwise it is very cpu time consuming
|
||||||
|
if (maxMeasure > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
maxMeasure++;
|
||||||
|
|
||||||
maxWidthOfCell = 0;
|
maxWidthOfCell = 0;
|
||||||
maxHeightOfCell = 0;
|
maxHeightOfCell = 0;
|
||||||
maxHeightSparseIntArray = new SparseIntArray();
|
maxHeightSparseIntArray.clear();
|
||||||
maxWidthSparseIntArray = new SparseIntArray();
|
maxWidthSparseIntArray.clear();
|
||||||
|
|
||||||
final int doubleCellPadding = cellPadding + cellPadding;
|
final int doubleCellPadding = cellPadding + cellPadding;
|
||||||
|
|
||||||
@@ -542,7 +549,6 @@ public class StickyHeaderTableView extends View implements NestedScrollingChild
|
|||||||
if (maxHeightSparseIntArray.get(i, 0) < textRectBounds.height()) {
|
if (maxHeightSparseIntArray.get(i, 0) < textRectBounds.height()) {
|
||||||
maxHeightSparseIntArray.put(i, textRectBounds.height());
|
maxHeightSparseIntArray.put(i, textRectBounds.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (j == 0) {
|
} else if (j == 0) {
|
||||||
// Left headers cells
|
// Left headers cells
|
||||||
if (data[i][j] instanceof String) {
|
if (data[i][j] instanceof String) {
|
||||||
@@ -557,10 +563,6 @@ public class StickyHeaderTableView extends View implements NestedScrollingChild
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
paintHeaderText.getTextBounds(str, 0, str.length(), textRectBounds);
|
paintHeaderText.getTextBounds(str, 0, str.length(), textRectBounds);
|
||||||
StaticLayout staticLayout = StaticLayout.Builder.obtain(str, 0, str.length(), paintHeaderText, textRectBounds.width()).build();
|
|
||||||
|
|
||||||
//textRectBounds.right = 50;
|
|
||||||
textRectBounds.bottom = staticLayout.getHeight();
|
|
||||||
} else if (data[i][j] instanceof Drawable) {
|
} else if (data[i][j] instanceof Drawable) {
|
||||||
Drawable icon = (Drawable) data[i][j];
|
Drawable icon = (Drawable) data[i][j];
|
||||||
textRectBounds.set(0,0,icon.getIntrinsicWidth(), icon.getIntrinsicHeight() / 2);
|
textRectBounds.set(0,0,icon.getIntrinsicWidth(), icon.getIntrinsicHeight() / 2);
|
||||||
@@ -613,9 +615,6 @@ public class StickyHeaderTableView extends View implements NestedScrollingChild
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
paintLabelText.getTextBounds(str, 0, str.length(), textRectBounds);
|
paintLabelText.getTextBounds(str, 0, str.length(), textRectBounds);
|
||||||
StaticLayout staticLayout = StaticLayout.Builder.obtain(str, 0, str.length(), paintLabelText, textRectBounds.width()).build();
|
|
||||||
|
|
||||||
textRectBounds.bottom = staticLayout.getHeight();
|
|
||||||
} else if (data[i][j] instanceof Drawable) {
|
} else if (data[i][j] instanceof Drawable) {
|
||||||
Drawable icon = (Drawable) data[i][j];
|
Drawable icon = (Drawable) data[i][j];
|
||||||
textRectBounds.set(0,0,icon.getIntrinsicWidth(), icon.getIntrinsicHeight() / 2);
|
textRectBounds.set(0,0,icon.getIntrinsicWidth(), icon.getIntrinsicHeight() / 2);
|
||||||
@@ -659,10 +658,12 @@ public class StickyHeaderTableView extends View implements NestedScrollingChild
|
|||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
|
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cellLeftX;
|
int cellLeftX;
|
||||||
int cellTopY = scrolledRect.top;
|
int cellTopY = scrolledRect.top;
|
||||||
int cellRightX;
|
int cellRightX;
|
||||||
|
@@ -22,6 +22,7 @@ import android.text.SpannableStringBuilder;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
import androidx.activity.OnBackPressedCallback;
|
import androidx.activity.OnBackPressedCallback;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
@@ -45,11 +46,16 @@ import java.util.List;
|
|||||||
public class TableFragment extends Fragment {
|
public class TableFragment extends Fragment {
|
||||||
private View tableView;
|
private View tableView;
|
||||||
|
|
||||||
|
private ProgressBar progressBar;
|
||||||
private StickyHeaderTableView tableDataView;
|
private StickyHeaderTableView tableDataView;
|
||||||
|
|
||||||
private List<MeasurementView> measurementViews;
|
private List<MeasurementView> measurementViews;
|
||||||
private List<ScaleMeasurement> scaleMeasurementList;
|
private List<ScaleMeasurement> scaleMeasurementList;
|
||||||
private ArrayList<Drawable> iconList;
|
private ArrayList<Drawable> iconList;
|
||||||
|
private final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
|
||||||
|
private final DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
|
||||||
|
private final DateFormat dayFormat = new SimpleDateFormat("EE");
|
||||||
|
private final SpannableStringBuilder contentFormat = new SpannableStringBuilder();
|
||||||
|
|
||||||
public TableFragment() {
|
public TableFragment() {
|
||||||
|
|
||||||
@@ -59,7 +65,9 @@ public class TableFragment extends Fragment {
|
|||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
tableView = inflater.inflate(R.layout.fragment_table, container, false);
|
tableView = inflater.inflate(R.layout.fragment_table, container, false);
|
||||||
|
|
||||||
|
progressBar = tableView.findViewById(R.id.progressBarTable);
|
||||||
tableDataView = tableView.findViewById(R.id.tableDataView);
|
tableDataView = tableView.findViewById(R.id.tableDataView);
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
tableDataView.setOnTableCellClickListener(new StickyHeaderTableView.OnTableCellClickListener() {
|
tableDataView.setOnTableCellClickListener(new StickyHeaderTableView.OnTableCellClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -83,7 +91,7 @@ public class TableFragment extends Fragment {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// measurementView.setUpdateViews(false);
|
measurementView.setUpdateViews(false);
|
||||||
|
|
||||||
measurementView.getIcon().setColorFilter(measurementView.getColor(), PorterDuff.Mode.SRC_ATOP);
|
measurementView.getIcon().setColorFilter(measurementView.getColor(), PorterDuff.Mode.SRC_ATOP);
|
||||||
iconList.add(measurementView.getIcon());
|
iconList.add(measurementView.getIcon());
|
||||||
@@ -105,7 +113,6 @@ public class TableFragment extends Fragment {
|
|||||||
|
|
||||||
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), onBackPressedCallback);
|
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), onBackPressedCallback);
|
||||||
|
|
||||||
|
|
||||||
return tableView;
|
return tableView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,9 +127,8 @@ public class TableFragment extends Fragment {
|
|||||||
tableData[0][j] = iconList.get(j);
|
tableData[0][j] = iconList.get(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
for (int i = 0; i<scaleMeasurementList.size(); i++ ) {
|
||||||
for (ScaleMeasurement scaleMeasurement : scaleMeasurementList) {
|
ScaleMeasurement scaleMeasurement = scaleMeasurementList.get(i);
|
||||||
int j=0;
|
|
||||||
|
|
||||||
ScaleMeasurement prevScaleMeasurement = null;
|
ScaleMeasurement prevScaleMeasurement = null;
|
||||||
|
|
||||||
@@ -130,32 +136,32 @@ public class TableFragment extends Fragment {
|
|||||||
prevScaleMeasurement = scaleMeasurementList.get(i+1);
|
prevScaleMeasurement = scaleMeasurementList.get(i+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int j=0;
|
||||||
for (MeasurementView measurementView : measurementViews) {
|
for (MeasurementView measurementView : measurementViews) {
|
||||||
if (!measurementView.isVisible() || measurementView instanceof UserMeasurementView || measurementView instanceof TimeMeasurementView) {
|
if (!measurementView.isVisible() || measurementView instanceof UserMeasurementView || measurementView instanceof TimeMeasurementView) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (measurementView instanceof DateMeasurementView) {
|
if (measurementView instanceof DateMeasurementView) {
|
||||||
String strDateTime = (DateFormat.getDateInstance(DateFormat.SHORT).format(scaleMeasurement.getDateTime()) +
|
String strDateTime = (dateFormat.format(scaleMeasurement.getDateTime()) +
|
||||||
" (" + new SimpleDateFormat("EE").format(scaleMeasurement.getDateTime()) + ")\n"+
|
" (" + dayFormat.format(scaleMeasurement.getDateTime()) + ")\n"+
|
||||||
DateFormat.getTimeInstance(DateFormat.SHORT).format(scaleMeasurement.getDateTime()));
|
timeFormat.format(scaleMeasurement.getDateTime()));
|
||||||
tableData[i+1][j] = strDateTime;
|
tableData[i+1][j] = strDateTime;
|
||||||
} else {
|
} else {
|
||||||
measurementView.loadFrom(scaleMeasurement, prevScaleMeasurement);
|
measurementView.loadFrom(scaleMeasurement, prevScaleMeasurement);
|
||||||
|
|
||||||
SpannableStringBuilder string = new SpannableStringBuilder();
|
contentFormat.clear();
|
||||||
string.append(measurementView.getValueAsString(false));
|
contentFormat.append(measurementView.getValueAsString(false));
|
||||||
measurementView.appendDiffValue(string, true);
|
measurementView.appendDiffValue(contentFormat, true, false);
|
||||||
|
|
||||||
tableData[i+1][j] = string.toString();
|
tableData[i+1][j] = contentFormat.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tableDataView.setData(tableData);
|
tableDataView.setData(tableData);
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:shtv_cellPadding="10dp"
|
app:shtv_cellPadding="16dp"
|
||||||
app:shtv_dividerColor="?android:colorBackground"
|
app:shtv_dividerColor="?android:colorBackground"
|
||||||
app:shtv_dividerThickness="1dp"
|
app:shtv_dividerThickness="1dp"
|
||||||
app:shtv_headerCellFillColor="?android:colorBackground"
|
app:shtv_headerCellFillColor="?android:colorBackground"
|
||||||
@@ -24,4 +24,15 @@
|
|||||||
app:shtv_textHeaderSize="14dp"
|
app:shtv_textHeaderSize="14dp"
|
||||||
app:shtv_textLabelColor="?android:colorForeground"
|
app:shtv_textLabelColor="?android:colorForeground"
|
||||||
app:shtv_textLabelSize="14dp" />
|
app:shtv_textLabelSize="14dp" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBarTable"
|
||||||
|
style="?android:attr/progressBarStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout >
|
</androidx.constraintlayout.widget.ConstraintLayout >
|
||||||
|
Reference in New Issue
Block a user