Android Velocity View寻呼机设置CurrentItem不工作

Android Velocity View寻呼机设置CurrentItem不工作,android,android-viewpager,Android,Android Viewpager,我正在使用VelocityViewPage来实现一个flingable ViewPager。我试图通过在VelocityViewPager的中间显示元素(日期1970)来设置视图寻呼机初始化。因此,在片段的onViewCreated()中,我执行以下操作: velocityViewPager.setCurrentItem(69); 一位用户建议执行以下操作,以在的评论中修复此问题: 但是,当我尝试此操作时,它不起作用,我将无法看到ViewPager的元素68、69和70,因为scrollX会被

我正在使用VelocityViewPage来实现一个flingable ViewPager。我试图通过在VelocityViewPager的中间显示元素(日期1970)来设置视图寻呼机初始化。因此,在片段的onViewCreated()中,我执行以下操作:

velocityViewPager.setCurrentItem(69);
一位用户建议执行以下操作,以在的评论中修复此问题:

但是,当我尝试此操作时,它不起作用,我将无法看到ViewPager的元素68、69和70,因为scrollX会被卡住,因为偏移量会将scrollX“锁定”到某个范围


我注意到的问题是scrollX被初始化为0,而它实际上应该是一个表示位置69的值。我试图用XML手动设置scrollX,用Java代码设置scrollX,并进行各种偏移量计算,但都无济于事

这就是我最终为一个令人畏惧的视角所做的。这肯定比仅仅从查看寻呼机扩展更痛苦(我需要大量的尝试和错误),但它给了我我想要的。您必须找到一种使用视图的scrollX的方法,以确定要捕捉到的项目以及到达视图的末尾或开头时要执行的操作

public class FlingableScroller extends View implements GestureDetector.OnGestureListener {

    public FlingableScroller(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, this);
        mScroller = new OverScroller(context);
        //This is how you "set current item" You will have to calculate INITIAL_SCROLL_X yourself
        setScrollX(INITIAL_SCROLL_X);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        animateFlingIfApplicable();
    }

    private void animateFlingIfApplicable() {
        //We have a fling only if computeScrollOffset is true.
        if (mScroller.computeScrollOffset()) {
            //Flinging passed the start point so continue the fling at the end
            if (mScroller.getFinalX() == 0) {
                int velocity = getFlingVelocity();
                mScroller.forceFinished(true);
                mScroller.fling(MAXIMUM_SCROLL_X, 0, velocity / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
                //Flinging passed the end point so continue the fling at the start
            } else if (mScroller.getFinalX() == MAXIMUM_SCROLL_X) {
                int velocity = getFlingVelocity();
                mScroller.forceFinished(true);
                mScroller.fling(0, 0, velocity / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
            } else if (mScroller.getFinalX() == getScrollX() || mScroller.getCurrVelocity() == 0) {
                snapToItem();
                mScroller.forceFinished(true);
            } else {
                scrollTo(mScroller.getCurrX(), 0);
            }
        }

        invalidate();
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        //This logic handles the case when you scroll pass the beginning or the end of the scroller
        if (getScrollX() > MAXIMUM_SCROLL_X) {
            scrollTo(0, 0);
        } else if (getScrollX() >= 0) {
            scrollBy(distance, 0);
        } else {
            scrollTo(MAXIMUM_SCROLL_X, 0);
        }
        invalidate();
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        //This is to prevent low velocity "flings"
        if (Math.abs(velocityX) < 400 * SCREEN_DENSITY) {
            return false;
        }

        mScroller.forceFinished(true);
        //Define friction_coefficient to a value that gives you desirable flinging.
        mScroller.fling(getScrollX(), getScrollY(), (int) -velocityX / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
        invalidate();
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mScroller.forceFinished(true);
                break;
            case MotionEvent.ACTION_UP:
                snapToItem();
                invalidate();
                break;
    }
        return mGestureDetector.onTouchEvent(event);
    }

    private void snapToItem() {
        //The the user lifts up their finger from a scroll or when a fling finishes determine what item to snap to. See the ViewPager source code to emulate the "fake drag"
        int scrollByValue = getScrollX() / SOME_VALUE
        scrollTo(scrollByValue, 0);
    }
}
公共类FlingableScroller扩展视图实现GestureDetector.OnTestureListener{
公共属性集(上下文、属性集属性){
超级(上下文,attrs);
mGestureDetector=新的GestureDetector(上下文,本);
mScroller=新的OverScroller(上下文);
//这是您“设置当前项目”的方式,您必须自己计算初始滚动
设置滚动条(初始滚动条);
}
@凌驾
受保护的void onDraw(画布){
super.onDraw(帆布);
animateflingifapplicate();
}
私有void animateflingifapplicate(){
//只有当computeScrollOffset为真时,我们才有机会。
if(mScroller.computeScrollOffset()){
//投掷已经过了起点,所以在终点继续投掷
if(mScroller.getFinalX()==0){
int velocity=getFlingVelocity();
mScroller.forceFinished(真);
mScroller.fling(最大滚动次数,0,速度/摩擦系数,0,0,最大滚动次数,0,0);
//投掷已过终点,因此在起点继续投掷
}else if(mScroller.getFinalX()==最大滚动次数){
int velocity=getFlingVelocity();
mScroller.forceFinished(真);
mScroller.fling(0,0,速度/摩擦系数,0,0,最大滚动X,0,0);
}else if(mScroller.getFinalX()==getScrollX()| | mScroller.getCurrVelocity()==0){
snapToItem();
mScroller.forceFinished(真);
}否则{
scrollTo(mScroller.getCurrX(),0);
}
}
使无效();
}
@凌驾
公共布尔onScroll(MotionEvent e1、MotionEvent e2、浮点距离X、浮点距离Y){
//当滚动通过滚动条的开始或结束时,此逻辑处理该情况
如果(getScrollX()>最大滚动次数){
滚动到(0,0);
}else if(getScrollX()>=0){
滚动(距离,0);
}否则{
滚动至(最大滚动次数,0);
}
使无效();
返回true;
}
@凌驾
公共布尔onFling(MotionEvent e1、MotionEvent e2、float-velocityX、float-velocityY){
//这是为了防止低速“抛掷”
if(数学绝对值(速度x)<400*屏幕密度){
返回false;
}
mScroller.forceFinished(真);
//将摩擦系数定义为可提供理想抛撒的值。
mScroller.fling(getScrollX(),getScrollY(),(int)-velocityX/摩擦系数,0,0,最大滚动系数,0,0);
使无效();
返回true;
}
@凌驾
公共布尔onTouchEvent(运动事件){
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
mScroller.forceFinished(真);
打破
case MotionEvent.ACTION\u UP:
snapToItem();
使无效();
打破
}
返回mGestureDetector.onTouchEvent(事件);
}
私有void snapToItem(){
//用户从卷轴上抬起手指或在投掷完成时确定要捕捉到的项目。请参阅ViewPager源代码以模拟“假拖动”
int scrollByValue=getScrollX()/SOME\u值
scrollTo(scrollByValue,0);
}
}
public class FlingableScroller extends View implements GestureDetector.OnGestureListener {

    public FlingableScroller(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, this);
        mScroller = new OverScroller(context);
        //This is how you "set current item" You will have to calculate INITIAL_SCROLL_X yourself
        setScrollX(INITIAL_SCROLL_X);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        animateFlingIfApplicable();
    }

    private void animateFlingIfApplicable() {
        //We have a fling only if computeScrollOffset is true.
        if (mScroller.computeScrollOffset()) {
            //Flinging passed the start point so continue the fling at the end
            if (mScroller.getFinalX() == 0) {
                int velocity = getFlingVelocity();
                mScroller.forceFinished(true);
                mScroller.fling(MAXIMUM_SCROLL_X, 0, velocity / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
                //Flinging passed the end point so continue the fling at the start
            } else if (mScroller.getFinalX() == MAXIMUM_SCROLL_X) {
                int velocity = getFlingVelocity();
                mScroller.forceFinished(true);
                mScroller.fling(0, 0, velocity / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
            } else if (mScroller.getFinalX() == getScrollX() || mScroller.getCurrVelocity() == 0) {
                snapToItem();
                mScroller.forceFinished(true);
            } else {
                scrollTo(mScroller.getCurrX(), 0);
            }
        }

        invalidate();
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        //This logic handles the case when you scroll pass the beginning or the end of the scroller
        if (getScrollX() > MAXIMUM_SCROLL_X) {
            scrollTo(0, 0);
        } else if (getScrollX() >= 0) {
            scrollBy(distance, 0);
        } else {
            scrollTo(MAXIMUM_SCROLL_X, 0);
        }
        invalidate();
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        //This is to prevent low velocity "flings"
        if (Math.abs(velocityX) < 400 * SCREEN_DENSITY) {
            return false;
        }

        mScroller.forceFinished(true);
        //Define friction_coefficient to a value that gives you desirable flinging.
        mScroller.fling(getScrollX(), getScrollY(), (int) -velocityX / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
        invalidate();
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mScroller.forceFinished(true);
                break;
            case MotionEvent.ACTION_UP:
                snapToItem();
                invalidate();
                break;
    }
        return mGestureDetector.onTouchEvent(event);
    }

    private void snapToItem() {
        //The the user lifts up their finger from a scroll or when a fling finishes determine what item to snap to. See the ViewPager source code to emulate the "fake drag"
        int scrollByValue = getScrollX() / SOME_VALUE
        scrollTo(scrollByValue, 0);
    }
}