黑马程序员技术交流社区

标题: [Android实例] Scroller类介绍 [打印本页]

作者: xingyunjunjun    时间: 2014-12-10 11:46
标题: [Android实例] Scroller类介绍
coller类是系统提供的一个高级滚动辅助类


系统自带的scrollTo和scrollBy滚动方法都是瞬间滚动~即直接移动到某位置,瞬移!
而有时候我们需要个平滑的滚动,有过程的滚动,甚至滚动结束后还有个惯性逐渐减速的滚动~
即跑到某个位置,我们可以看到从起点到终点的过程
而实现这种"有过程"的滚动~就需要用到Scroller类了
可以撸个代码,参考ScrollView类的scrollTo和smoothScrollTo方法的区别理解下带"过程"是怎么样的~




但Scroller只是用于跟踪控件滑动的轨迹,此类不会移动控件,只相当于一个滚动轨迹记录工具所以需要你在View的一个回调函数computerScroll()中使用Scroller对象获取滑动的数据,
最后还是用scrollTo/By方法来实际控制某个View的滚动行为


比如下面的简化版smoothScroll方法
    // 调用此方法滚动到目标位置
    public void smoothScrollTo( int fx, int fy) {
        int dx = fx - mScroller.getFinalX();
        int dy = fy - mScroller.getFinalY();
        smoothScrollBy (dx, dy);
    }



    // 调用此方法设置滚动的相对偏移
    public void smoothScrollBy( int dx, int dy) {

        // 设置mScroller的滚动偏移量
        mScroller.startScroll( mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
        // 这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
        invalidate();
    }

Scroller提供的除startScroll外,还有fling等有过程的移动方法,
查看Scroller源码会发现,方法中只会记录数值currentX/Y finalX/Y等等~
即只相当于轨迹记录作用

而实际移动则需要在view中的computScroll方法里处理,如下


    @Override
    public void computeScroll() {

        // 先判断mScroller滚动是否完成
        if (mScroller.computeScrollOffset()) {

            // 这里调用View的scrollTo()完成实际的滚动
            scrollTo( mScroller.getCurrX(), mScroller .getCurrY());

            // 必须调用该方法,否则不一定能看到滚动效果
            invalidate();
        }
        super.computeScroll();
    }


mScroller.computeScrollOffset方法是判断滚动过程是否完成的,
如果没有完成则需要不停的scrollTo到新目标位置~
所以在if最末需要加一个invalidate(),该方法会再次触发computScroll,直到判断滚动已经完成为止
相当于一个while循环~


判断mScroller余下的滚动是否还有未完成的部分,
是的话则滚动到Scroller计算的currentX/Y,然后invalidate刷新页面~
invalidate的时候又会触发computeScroll方法,然后继续判断
直到判断滚动完全完成了,则结束~





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2