Scroller.fling() 未按预期工作
Scroller.fling() isn't working as expected
这是我用来接收触摸事件的代码,并将它们提供给我的 canvas 用于翻译的 x,y :
VelocityTracker mVelocity;
Scroller scroller;
@Override
public boolean onTouchEvent(MotionEvent event) { //On touch
super.onTouchEvent(event);
mVelocity = VelocityTracker.obtain();
mVelocity.addMovement(event);
//Log.d("VELOCITY","("+mVelocity.getXVelocity()+","+mVelocity.getYVelocity()+")");
if(event.getActionMasked()==MotionEvent.ACTION_MOVE){ //If it's a drag, call scrollMove
mVelocity.computeCurrentVelocity(1);
scrollMove();
}
if(event.getActionMasked()==MotionEvent.ACTION_UP) { //or scrollFling
mVelocity.computeCurrentVelocity(1);
scrollFling();
}
mVelocity.recycle();
return true;
}
void scrollMove(){ //Canvas is constantly translating by (scrollMove.x,scrollMove.y) every time invalidate() is called
scrollMove.x += mVelocity.getXVelocity() * 10f;
scrollMove.y += mVelocity.getYVelocity() * 10f;
invalidate();
}
void scrollFling(){ //how does scroller.fling work?
scroller.fling(getScrollX(),getScrollY(),(int)-mVelocity.getXVelocity(),(int)-mVelocity.getYVelocity(),0,0,10000,10000);
invalidate();
}
@Override
public void computeScroll() {
super.computeScroll();
if(!scroller.isFinished()){
scroller.computeScrollOffset();
scrollMove.x += scroller.getCurrX();
scrollMove.y += scroller.getCurrY();
//postInvalidateOnAnimation();
postInvalidateOnAnimation(); //Alternated between all 3 of these
postInvalidate(); //??
invalidate(); //??
Log.d("FLING","Should be flinging"); //This is only called once
}
}
所以滚动是按我预期的那样工作,但快速移动不是。虽然 scroll 方法不断被调用到 return 值并转换 canvas,fling 只被调用一次,并且 return 是我放入函数调用的任何最大值。
我认为 scroller.fling / computeScroll 是每帧的递归回调,并且只要投掷没有结束,我就会收到有关在哪里转换我的视图的信息?我做错了什么?
(感谢来自 irc.freenode/android-dev 的@Roughy)
这里的第一个问题是您将错误的值传递给 .fling()
scroller.fling(startX, startY, velX, velY, minX, MAXX, MINY, MAXY);
你翻转了 min/max。
第二个问题是每次移动事件发生变化时都会调用 mVelocity = VelocityTracker.obtain();
,这会为每个运动帧创建一个新的速度跟踪器,您应该只在 [=12= 上调用一次],然后在 ACTION_MOVE 和 ACTION_UP.
上调用 mVelocity.addMovement(event);
也在 ACTION_UP 上调用 mVelocity.recycle();
。
这是我用来接收触摸事件的代码,并将它们提供给我的 canvas 用于翻译的 x,y :
VelocityTracker mVelocity;
Scroller scroller;
@Override
public boolean onTouchEvent(MotionEvent event) { //On touch
super.onTouchEvent(event);
mVelocity = VelocityTracker.obtain();
mVelocity.addMovement(event);
//Log.d("VELOCITY","("+mVelocity.getXVelocity()+","+mVelocity.getYVelocity()+")");
if(event.getActionMasked()==MotionEvent.ACTION_MOVE){ //If it's a drag, call scrollMove
mVelocity.computeCurrentVelocity(1);
scrollMove();
}
if(event.getActionMasked()==MotionEvent.ACTION_UP) { //or scrollFling
mVelocity.computeCurrentVelocity(1);
scrollFling();
}
mVelocity.recycle();
return true;
}
void scrollMove(){ //Canvas is constantly translating by (scrollMove.x,scrollMove.y) every time invalidate() is called
scrollMove.x += mVelocity.getXVelocity() * 10f;
scrollMove.y += mVelocity.getYVelocity() * 10f;
invalidate();
}
void scrollFling(){ //how does scroller.fling work?
scroller.fling(getScrollX(),getScrollY(),(int)-mVelocity.getXVelocity(),(int)-mVelocity.getYVelocity(),0,0,10000,10000);
invalidate();
}
@Override
public void computeScroll() {
super.computeScroll();
if(!scroller.isFinished()){
scroller.computeScrollOffset();
scrollMove.x += scroller.getCurrX();
scrollMove.y += scroller.getCurrY();
//postInvalidateOnAnimation();
postInvalidateOnAnimation(); //Alternated between all 3 of these
postInvalidate(); //??
invalidate(); //??
Log.d("FLING","Should be flinging"); //This is only called once
}
}
所以滚动是按我预期的那样工作,但快速移动不是。虽然 scroll 方法不断被调用到 return 值并转换 canvas,fling 只被调用一次,并且 return 是我放入函数调用的任何最大值。
我认为 scroller.fling / computeScroll 是每帧的递归回调,并且只要投掷没有结束,我就会收到有关在哪里转换我的视图的信息?我做错了什么?
(感谢来自 irc.freenode/android-dev 的@Roughy)
这里的第一个问题是您将错误的值传递给 .fling()
scroller.fling(startX, startY, velX, velY, minX, MAXX, MINY, MAXY);
你翻转了 min/max。
第二个问题是每次移动事件发生变化时都会调用 mVelocity = VelocityTracker.obtain();
,这会为每个运动帧创建一个新的速度跟踪器,您应该只在 [=12= 上调用一次],然后在 ACTION_MOVE 和 ACTION_UP.
mVelocity.addMovement(event);
也在 ACTION_UP 上调用 mVelocity.recycle();
。