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; 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,73 +35,105 @@ 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) @Override
public boolean onTouchEvent(MotionEvent event)
{ {
int newDataOffset = dataOffset + (int) (dx / columnWidth); return detector.onTouchEvent(event);
newDataOffset = Math.max(0, newDataOffset); }
if (newDataOffset != dataOffset) @Override
{ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
dataOffset = newDataOffset; {
invalidate(); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return true; setMeasuredDimension(getMeasuredWidth(), columnHeight + headerHeight + footerHeight);
}
else return false;
} }
@Override @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); @Override
final float x = MotionEventCompat.getX(event, pointerIndex); public boolean onDown(MotionEvent e)
final float y = MotionEventCompat.getY(event, pointerIndex); {
return true;
}
if (action == MotionEvent.ACTION_DOWN) @Override
{ public void onShowPress(MotionEvent e)
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; @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); 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; return true;
} }
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) public void onLongPress(MotionEvent e)
{ {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), columnHeight + headerHeight + footerHeight);
} }
@Override @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); scroller.fling(scroller.getCurrX(), scroller.getCurrY(), (int) velocityX / 2, 0, 0, 100000,
nColumns = w / columnWidth; 0, 0);
fetchData(); 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