【问题标题】:Android Gallery Fling: how to calculate the necessary velocity for a flingAndroid Gallery Fling:如何计算必要的速度
【发布时间】:2012-09-13 12:11:17
【问题描述】:

我必须实现一个画廊,它会在动画中移动到下一张幻灯片。我在这里找到了一些解决方案: 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?

目标:计算正确的速度 X 以从一张幻灯片平滑滚动到另一张幻灯片,无论是向左还是向右。速度以像素/秒计算。如果我提供的速度太小,那么图像会滚动一点并返回到前一个。如果速度太大,那么它会滚动超过一个图像,但我需要它一个接一个地滚动到下一个/上一个图像,即使距离非常小。 我发现尝试时,最佳值略大于设备宽度,但我想知道是否所有设备都是这种情况。

【问题讨论】:

    标签: android gallery


    【解决方案1】:

    聚会有点晚了。 AOSP 提供了 2 个类来帮助您计算速度,VelocityTrackerViewConfiguration。跟踪器消耗 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;
            }
        });
    

    【讨论】:

    • 感谢速度跟踪器的想法
    • 使用上述实现的问题是 Time as fling 应该在一定时间过去之后是不可能的。现在您可以在不松开手指的情况下移动手指(Action_UP),并且弹射方向会改变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-03-18
    相关资源
    最近更新 更多