mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Fix a few issues with header scrolling
This commit is contained in:
@@ -33,7 +33,9 @@ public abstract class ScrollableChart extends View
|
||||
|
||||
private int dataOffset;
|
||||
|
||||
private int scrollerBucketSize;
|
||||
private int scrollerBucketSize = 1;
|
||||
|
||||
private int direction = 1;
|
||||
|
||||
private GestureDetector detector;
|
||||
|
||||
@@ -43,10 +45,7 @@ public abstract class ScrollableChart extends View
|
||||
|
||||
private ScrollController scrollController;
|
||||
|
||||
public void setScrollController(ScrollController scrollController)
|
||||
{
|
||||
this.scrollController = scrollController;
|
||||
}
|
||||
private int maxDataOffset = 10000;
|
||||
|
||||
public ScrollableChart(Context context)
|
||||
{
|
||||
@@ -79,19 +78,6 @@ public abstract class ScrollableChart extends View
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDataOffset()
|
||||
{
|
||||
int newDataOffset =
|
||||
Math.max(0, scroller.getCurrX() / scrollerBucketSize);
|
||||
|
||||
if(newDataOffset != dataOffset)
|
||||
{
|
||||
dataOffset = newDataOffset;
|
||||
scrollController.onDataOffsetChanged(dataOffset);
|
||||
postInvalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e)
|
||||
{
|
||||
@@ -105,19 +91,44 @@ public abstract class ScrollableChart extends View
|
||||
float velocityY)
|
||||
{
|
||||
scroller.fling(scroller.getCurrX(), scroller.getCurrY(),
|
||||
(int) velocityX / 2, 0, 0, 100000, 0, 0);
|
||||
direction * ((int) velocityX) / 2, 0, 0, getMaxX(), 0, 0);
|
||||
invalidate();
|
||||
|
||||
scrollAnimator.setDuration(scroller.getDuration());
|
||||
scrollAnimator.start();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e)
|
||||
private int getMaxX()
|
||||
{
|
||||
return maxDataOffset * scrollerBucketSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state)
|
||||
{
|
||||
BundleSavedState bss = (BundleSavedState) state;
|
||||
int x = bss.bundle.getInt("x");
|
||||
int y = bss.bundle.getInt("y");
|
||||
direction = bss.bundle.getInt("direction");
|
||||
dataOffset = bss.bundle.getInt("dataOffset");
|
||||
maxDataOffset = bss.bundle.getInt("maxDataOffset");
|
||||
scroller.startScroll(0, 0, x, y, 0);
|
||||
scroller.computeScrollOffset();
|
||||
super.onRestoreInstanceState(bss.getSuperState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState()
|
||||
{
|
||||
Parcelable superState = super.onSaveInstanceState();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("x", scroller.getCurrX());
|
||||
bundle.putInt("y", scroller.getCurrY());
|
||||
bundle.putInt("dataOffset", dataOffset);
|
||||
bundle.putInt("direction", direction);
|
||||
bundle.putInt("maxDataOffset", maxDataOffset);
|
||||
return new BundleSavedState(superState, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,11 +142,14 @@ public abstract class ScrollableChart extends View
|
||||
if (parent != null) parent.requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
|
||||
scroller.startScroll(scroller.getCurrX(), scroller.getCurrY(),
|
||||
(int) -dx, (int) dy, 0);
|
||||
|
||||
dx = - direction * dx;
|
||||
dx = Math.min(dx, getMaxX() - scroller.getCurrX());
|
||||
scroller.startScroll(scroller.getCurrX(), scroller.getCurrY(), (int) dx,
|
||||
(int) dy, 0);
|
||||
|
||||
scroller.computeScrollOffset();
|
||||
updateDataOffset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -157,34 +171,37 @@ public abstract class ScrollableChart extends View
|
||||
return detector.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public void setDirection(int direction)
|
||||
{
|
||||
if (direction != 1 && direction != -1)
|
||||
throw new IllegalArgumentException();
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void setMaxDataOffset(int maxDataOffset)
|
||||
{
|
||||
this.maxDataOffset = maxDataOffset;
|
||||
this.dataOffset = Math.min(dataOffset, maxDataOffset);
|
||||
scrollController.onDataOffsetChanged(this.dataOffset);
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
public void setScrollController(ScrollController scrollController)
|
||||
{
|
||||
this.scrollController = scrollController;
|
||||
}
|
||||
|
||||
public void setScrollerBucketSize(int scrollerBucketSize)
|
||||
{
|
||||
this.scrollerBucketSize = scrollerBucketSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state)
|
||||
{
|
||||
BundleSavedState bss = (BundleSavedState) state;
|
||||
int x = bss.bundle.getInt("x");
|
||||
int y = bss.bundle.getInt("y");
|
||||
dataOffset = bss.bundle.getInt("dataOffset");
|
||||
scroller.startScroll(0, 0, x, y, 0);
|
||||
scroller.computeScrollOffset();
|
||||
super.onRestoreInstanceState(bss.getSuperState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState()
|
||||
{
|
||||
Parcelable superState = super.onSaveInstanceState();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("x", scroller.getCurrX());
|
||||
bundle.putInt("y", scroller.getCurrY());
|
||||
bundle.putInt("dataOffset", dataOffset);
|
||||
return new BundleSavedState(superState, bundle);
|
||||
}
|
||||
|
||||
private void init(Context context)
|
||||
{
|
||||
detector = new GestureDetector(context, this);
|
||||
@@ -194,6 +211,20 @@ public abstract class ScrollableChart extends View
|
||||
scrollController = new ScrollController() {};
|
||||
}
|
||||
|
||||
private void updateDataOffset()
|
||||
{
|
||||
int newDataOffset = scroller.getCurrX() / scrollerBucketSize;
|
||||
newDataOffset = Math.max(0, newDataOffset);
|
||||
newDataOffset = Math.min(maxDataOffset, newDataOffset);
|
||||
|
||||
if (newDataOffset != dataOffset)
|
||||
{
|
||||
dataOffset = newDataOffset;
|
||||
scrollController.onDataOffsetChanged(dataOffset);
|
||||
postInvalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public interface ScrollController
|
||||
{
|
||||
default void onDataOffsetChanged(int newDataOffset) {}
|
||||
|
||||
@@ -164,6 +164,7 @@ public class ListHabitsRootView extends BaseRootView
|
||||
{
|
||||
int count = getCheckmarkCount();
|
||||
header.setButtonCount(count);
|
||||
header.setMaxDataOffset(Math.max(MAX_CHECKMARK_COUNT - count, 0));
|
||||
listView.setCheckmarkCount(count);
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.InterfaceUtils.*;
|
||||
|
||||
public class HeaderView extends ScrollableChart
|
||||
implements Preferences.Listener, MidnightTimer.MidnightListener
|
||||
{
|
||||
@@ -52,6 +50,8 @@ public class HeaderView extends ScrollableChart
|
||||
|
||||
private RectF rect;
|
||||
|
||||
private int maxDataOffset;
|
||||
|
||||
public HeaderView(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
@@ -61,18 +61,6 @@ public class HeaderView extends ScrollableChart
|
||||
setButtonCount(5);
|
||||
}
|
||||
|
||||
StyledResources res = new StyledResources(context);
|
||||
setScrollerBucketSize((int) dpToPixels(context, 42));
|
||||
paint = new TextPaint();
|
||||
paint.setColor(Color.BLACK);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setTextSize(getResources().getDimension(R.dimen.tinyTextSize));
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
paint.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
paint.setColor(res.getColor(R.attr.mediumContrastTextColor));
|
||||
|
||||
rect = new RectF();
|
||||
|
||||
Context appContext = context.getApplicationContext();
|
||||
if (appContext instanceof HabitsApplication)
|
||||
{
|
||||
@@ -85,6 +73,21 @@ public class HeaderView extends ScrollableChart
|
||||
ListHabitsActivity activity = (ListHabitsActivity) context;
|
||||
midnightTimer = activity.getListHabitsComponent().getMidnightTimer();
|
||||
}
|
||||
|
||||
Resources res = context.getResources();
|
||||
setScrollerBucketSize((int) res.getDimension(R.dimen.checkmarkWidth));
|
||||
setDirection(shouldReverseCheckmarks() ? 1 : -1);
|
||||
|
||||
StyledResources sr = new StyledResources(context);
|
||||
paint = new TextPaint();
|
||||
paint.setColor(Color.BLACK);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setTextSize(getResources().getDimension(R.dimen.tinyTextSize));
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
paint.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
paint.setColor(sr.getColor(R.attr.mediumContrastTextColor));
|
||||
|
||||
rect = new RectF();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,6 +99,7 @@ public class HeaderView extends ScrollableChart
|
||||
@Override
|
||||
public void onCheckmarkOrderChanged()
|
||||
{
|
||||
setDirection(shouldReverseCheckmarks() ? 1 : -1);
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
@@ -137,24 +141,26 @@ public class HeaderView extends ScrollableChart
|
||||
super.onDraw(canvas);
|
||||
|
||||
GregorianCalendar day = DateUtils.getStartOfTodayCalendar();
|
||||
|
||||
Resources res = getContext().getResources();
|
||||
float width = res.getDimension(R.dimen.checkmarkWidth);
|
||||
float height = res.getDimension(R.dimen.checkmarkHeight);
|
||||
rect.set(0, 0, width, height);
|
||||
rect.offset(canvas.getWidth(), 0);
|
||||
boolean reverse = shouldReverseCheckmarks();
|
||||
|
||||
day.add(GregorianCalendar.DAY_OF_MONTH, -getDataOffset());
|
||||
float em = paint.measureText("m");
|
||||
|
||||
for (int i = 0; i < buttonCount; i++)
|
||||
{
|
||||
rect.offset(-width, 0);
|
||||
rect.set(0, 0, width, height);
|
||||
rect.offset(canvas.getWidth(), 0);
|
||||
if(reverse) rect.offset(- (i + 1) * width, 0);
|
||||
else rect.offset((i - buttonCount) * width, 0);
|
||||
|
||||
String text = DateUtils.formatHeaderDate(day).toUpperCase();
|
||||
String[] lines = text.split("\n");
|
||||
|
||||
int y1 = (int)(rect.centerY() - 0.5 * em);
|
||||
int y2 = (int)(rect.centerY() + em);
|
||||
int y1 = (int)(rect.centerY() - 0.25 * em);
|
||||
int y2 = (int)(rect.centerY() + 1.25 * em);
|
||||
|
||||
canvas.drawText(lines[0], rect.centerX(), y1, paint);
|
||||
canvas.drawText(lines[1], rect.centerX(), y2, paint);
|
||||
|
||||
Reference in New Issue
Block a user