我必须实现一个画廊,在动画播放时移动到下一张幻灯片。我在这里找到了一些解决方案: How to have scrolling animation programmatically
我正在使用此代码:
//scroll forward or backward
private void scroll(int type){
View selectedV = mG.getSelectedView();
int idx = mG.indexOfChild(selectedV);
switch(type){
case FORWARD:
default:
if(idx<mG.getChildCount()-1)
idx++;
break;
case BACKWARD:
if(idx>0)
idx--;
break;
}
//now scrolled view's child idx in gallery is gotten
View nextView = mG.getChildAt(idx);
//(x,y) in scrolled view is gotten
int x = nextView.getLeft()+nextView.getWidth()/2;
int y = nextView.getTop()+nextView.getHeight()/2;
String out = String.format("x=%d, y=%d", x, y);
Log.i(TAG+".scroll", out);
//Kurru's simulating clicking view
MotionEvent event = MotionEvent.obtain(100, 100, MotionEvent.ACTION_DOWN, x, y, 0);
mG.onDown(event);
boolean res = mG.onSingleTapUp(null);
Log.i(TAG+".scroll", "onSingleTapUp return =" + res);
}
问题是它只有在我看到3张图像时才有效,而且显然它甚至不能在某些设备上运行。
但是,当我一次显示一个图像时(它们占据几乎所有设备宽度),此方法不起作用。这就是我实施以下方法的原因:
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if(e1 == null || e2 == null) return false;
if (isScrollingLeft(e1, e2)) { // Check if scrolling left
if(State.curentZoom==0)
return super.onFling(e1, e2, State.imgWidthBig*1.1f, 0);
else {
scroll(BACKWARD);
return true;
}
} else if (isScrollingRight(e1, e2)) { // Otherwise scrolling right
if(State.curentZoom==0)
return super.onFling(e1, e2, (-1)*State.imgWidthBig*1.1f, 0);
else {
scroll(FORWARD);
return true;
}
} else
return false;
}
使用其他帖子的代码: How to stop scrolling in a Gallery Widget?
目标:计算正确的velocityX,使其从一张幻灯片平滑滚动到另一张幻灯片,无论是向左还是向右。速度以像素/秒计算。如果我提供的速度太小,那么图像将滚动一点并返回到前一个。如果速度太大,那么它将滚动到多个图像,但是我需要它一个接一个地滚动到下一个/上一个图像,即使距离非常小。 我发现尝试,最好的值略大于设备宽度,但我想知道是否所有设备都是如此。
答案 0 :(得分:3)
派对有点晚了。 AOSP提供2个类来帮助您计算速度,VelocityTracker
&amp; ViewConfiguration
。跟踪器消耗MotionEvents并输出X / Y速度。而ViewConfiguration声明了不同手势类型的阈值。
下面是一个使用2个类来检测投掷手势的简单示例。
mVelocityTracker = VelocityTracker.obtain();
mViewConfiguration = ViewConfiguration.get(mContext);
mListView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
final int action = event.getActionMasked();
mVelocityTracker.addMovement(event);
if (action == MotionEvent.ACTION_UP) {
mVelocityTracker.computeCurrentVelocity(1000, mViewConfiguration.getScaledMaximumFlingVelocity());
if (mVelocityTracker.getXVelocity() > mViewConfiguration.getScaledMinimumFlingVelocity()) {
// horizontal fling!
return true;
}
}
return false;
}
});