From f9a9339042b3b1acc06857993619dd65191ecee6 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Thu, 25 Feb 2016 21:30:03 -0500 Subject: [PATCH] Use GestureDetector for scrolling --- .../uhabits/views/ScrollableDataView.java | 117 ++++++++++++------ 1 file changed, 76 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/org/isoron/uhabits/views/ScrollableDataView.java b/app/src/main/java/org/isoron/uhabits/views/ScrollableDataView.java index fbad9d127..cdd7bf99e 100644 --- a/app/src/main/java/org/isoron/uhabits/views/ScrollableDataView.java +++ b/app/src/main/java/org/isoron/uhabits/views/ScrollableDataView.java @@ -19,12 +19,15 @@ package org.isoron.uhabits.views; +import android.animation.ValueAnimator; import android.content.Context; -import android.support.v4.view.MotionEventCompat; +import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; +import android.widget.Scroller; -public abstract class ScrollableDataView extends View +public abstract class ScrollableDataView extends View implements GestureDetector.OnGestureListener, + ValueAnimator.AnimatorUpdateListener { protected int dataOffset; @@ -32,73 +35,105 @@ public abstract class ScrollableDataView extends View protected int columnWidth, columnHeight; protected int headerHeight, footerHeight; - private float prevX, prevY; + private GestureDetector detector; + private Scroller scroller; + private ValueAnimator scrollAnimator; public ScrollableDataView(Context context) { super(context); + + detector = new GestureDetector(context, this); + scroller = new Scroller(context, null, true); + scrollAnimator = ValueAnimator.ofFloat(0, 1); + scrollAnimator.addUpdateListener(this); } protected abstract void fetchData(); - protected boolean move(float dx) + @Override + public boolean onTouchEvent(MotionEvent event) { - int newDataOffset = dataOffset + (int) (dx / columnWidth); - newDataOffset = Math.max(0, newDataOffset); + return detector.onTouchEvent(event); + } - if (newDataOffset != dataOffset) - { - dataOffset = newDataOffset; - invalidate(); - return true; - } - else return false; + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) + { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + setMeasuredDimension(getMeasuredWidth(), columnHeight + headerHeight + footerHeight); } @Override - public boolean onTouchEvent(MotionEvent event) + protected void onSizeChanged(int w, int h, int oldw, int oldh) { - int action = event.getAction(); + super.onSizeChanged(w, h, oldw, oldh); + nColumns = w / columnWidth; + fetchData(); + } - int pointerIndex = MotionEventCompat.getActionIndex(event); - final float x = MotionEventCompat.getX(event, pointerIndex); - final float y = MotionEventCompat.getY(event, pointerIndex); + @Override + public boolean onDown(MotionEvent e) + { + return true; + } - if (action == MotionEvent.ACTION_DOWN) - { - prevX = x; - prevY = y; - } + @Override + public void onShowPress(MotionEvent e) + { - if (action == MotionEvent.ACTION_MOVE) - { - float dx = x - prevX; - float dy = y - prevY; + } - if (Math.abs(dy) > Math.abs(dx)) return false; + @Override + public boolean onSingleTapUp(MotionEvent e) + { + return false; + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float dx, float dy) + { + if(Math.abs(dx) > Math.abs(dy)) getParent().requestDisallowInterceptTouchEvent(true); - if (move(dx)) - { - prevX = x; - prevY = y; - } - } + scroller.startScroll(scroller.getCurrX(), scroller.getCurrY(), (int) -dx, (int) dy, 0); + scroller.computeScrollOffset(); + dataOffset = Math.max(0, scroller.getCurrX() / columnWidth); + postInvalidate(); return true; } @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) + public void onLongPress(MotionEvent e) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - setMeasuredDimension(getMeasuredWidth(), columnHeight + headerHeight + footerHeight); + } @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - super.onSizeChanged(w, h, oldw, oldh); - nColumns = w / columnWidth; - fetchData(); + scroller.fling(scroller.getCurrX(), scroller.getCurrY(), (int) velocityX / 2, 0, 0, 100000, + 0, 0); + invalidate(); + + scrollAnimator.setDuration(scroller.getDuration()); + scrollAnimator.start(); + + return false; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) + { + if (!scroller.isFinished()) + { + scroller.computeScrollOffset(); + dataOffset = Math.max(0, scroller.getCurrX() / columnWidth); + postInvalidate(); + } + else + { + scrollAnimator.cancel(); + } } }