Use GestureDetector for scrolling

This commit is contained in:
2016-02-25 21:30:03 -05:00
parent 5e21d877c5
commit f9a9339042

View File

@@ -19,12 +19,15 @@
package org.isoron.uhabits.views; package org.isoron.uhabits.views;
import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.support.v4.view.MotionEventCompat; import android.view.GestureDetector;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; 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; protected int dataOffset;
@@ -32,59 +35,26 @@ public abstract class ScrollableDataView extends View
protected int columnWidth, columnHeight; protected int columnWidth, columnHeight;
protected int headerHeight, footerHeight; protected int headerHeight, footerHeight;
private float prevX, prevY; private GestureDetector detector;
private Scroller scroller;
private ValueAnimator scrollAnimator;
public ScrollableDataView(Context context) public ScrollableDataView(Context context)
{ {
super(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 abstract void fetchData();
protected boolean move(float dx)
{
int newDataOffset = dataOffset + (int) (dx / columnWidth);
newDataOffset = Math.max(0, newDataOffset);
if (newDataOffset != dataOffset)
{
dataOffset = newDataOffset;
invalidate();
return true;
}
else return false;
}
@Override @Override
public boolean onTouchEvent(MotionEvent event) public boolean onTouchEvent(MotionEvent event)
{ {
int action = event.getAction(); return detector.onTouchEvent(event);
int pointerIndex = MotionEventCompat.getActionIndex(event);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
if (action == MotionEvent.ACTION_DOWN)
{
prevX = x;
prevY = y;
}
if (action == MotionEvent.ACTION_MOVE)
{
float dx = x - prevX;
float dy = y - prevY;
if (Math.abs(dy) > Math.abs(dx)) return false;
getParent().requestDisallowInterceptTouchEvent(true);
if (move(dx))
{
prevX = x;
prevY = y;
}
}
return true;
} }
@Override @Override
@@ -101,4 +71,69 @@ public abstract class ScrollableDataView extends View
nColumns = w / columnWidth; nColumns = w / columnWidth;
fetchData(); fetchData();
} }
@Override
public boolean onDown(MotionEvent e)
{
return true;
}
@Override
public void onShowPress(MotionEvent e)
{
}
@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);
scroller.startScroll(scroller.getCurrX(), scroller.getCurrY(), (int) -dx, (int) dy, 0);
scroller.computeScrollOffset();
dataOffset = Math.max(0, scroller.getCurrX() / columnWidth);
postInvalidate();
return true;
}
@Override
public void onLongPress(MotionEvent e)
{
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
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();
}
}
} }