Use GestureDetector for scrolling

pull/30/head
Alinson S. Xavier 10 years ago
parent 5e21d877c5
commit f9a9339042

@ -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)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
dataOffset = newDataOffset;
invalidate();
return true;
}
else return false;
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();
int pointerIndex = MotionEventCompat.getActionIndex(event);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
super.onSizeChanged(w, h, oldw, oldh);
nColumns = w / columnWidth;
fetchData();
}
if (action == MotionEvent.ACTION_DOWN)
@Override
public boolean onDown(MotionEvent e)
{
prevX = x;
prevY = y;
return true;
}
if (action == MotionEvent.ACTION_MOVE)
@Override
public void onShowPress(MotionEvent e)
{
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;
}
@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
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();
}
}
}

Loading…
Cancel
Save