Scroller的使用

Scroller 是一个实现 View 平滑滚动的辅助类,在使用它之前,需要通过 startScroll 来设置滚动参数,即起始点坐标和(x , y)轴上要滚动的距离。
相关方法有:

mScroller.getCurrX() //获取mScroller当前水平滚动的位置  
mScroller.getCurrY() //获取mScroller当前竖直滚动的位置  
mScroller.getFinalX() //获取mScroller最终停止的水平位置  
mScroller.getFinalY() //获取mScroller最终停止的竖直位置  
mScroller.setFinalX(int newX) //设置mScroller最终停留的水平位置,没有动画效果,直接跳到目标位置  
mScroller.setFinalY(int newY) //设置mScroller最终停留的竖直位置,没有动画效果,直接跳到目标位置  

//滚动,startX, startY为开始滚动的位置,dx,dy为滚动的偏移量(注意:是偏移量,不是最终坐标), duration为完成滚动的时间  
mScroller.startScroll(int startX, int startY, int dx, int dy) //内部默认执行时间250ms  
mScroller.startScroll(int startX, int startY, int dx, int dy, int duration)  

mScroller.computeScrollOffset() //返回值为boolean,true说明滚动尚未完成,false说明滚动已经完成。这是一个很重要的方法,通常放在View.computeScroll()中,用来判断是否滚动是否结束。  

从上面 startScroll 方法可以看到,Scroller 它自己封装了滚动时间,滚动的目标位置,以及在每个时间内View应该滚动到的(x , y ) 轴坐标点。这样就可以在有效的滚动周期内通过 Scroller 的 getCurrX() 和 getCurrY() 来获取当前时刻View应该滚动的位置,然后通过调用 View 的 scrollTo 或者 ScrollBy 方法进行滚动。

getCurrX() 和getCurrY()可能有点不太好理解,从startScroll方法调用开始,它会在设定的滚动时间内(默认的250ms)持续滚动到目标位置,在它没有抵达目标位置之前,它是一直在滚动的,getCurrX() 和 getCurrY() 方法获取的是调用时 Scroller 所滚动的位置。

我们只需要重写 View 类的 computeScroll 方法,该方法是在 View 绘制时被调用,在里面调用 Scroller 的 computeScrollOffset 来判断滚动是否完成,没完成则继续通过 scrollTo 或者 ScrollBy 进行滚动视图,然后调用目标 View 的 postInvalidate() 或者 invalidate() 进行 View 重绘,View 的重绘又导致 computeScroll 方法被调用。所以,这里就形成了一个递归,结束标识就是当 View 滚动到 Scroller 所设定的目标位置(Scroller.computeScrollOffset() == true)。

这里是写的一个实例:

public class ScrollLayout extends LinearLayout {

    Scroller scroller;

    public ScrollLayout(Context context) {
        super(context);
        scroller = new Scroller(context);
    }

    // 该方法会在View重绘的时候调用
    @Override
    public void computeScroll() {
        // 判断scroller是否已滚动到指定位置
        if (scroller.computeScrollOffset()) {
            // 使View滚动到目前的位置
            this.scrollTo(scroller.getCurrX(), scroller.getCurrY());
            // 重绘View,从而导致 computeScroll()被调用,开启递归模式,直到scroller.computeScrollOffset()返回false。
            postInvalidate();
        }
    }

    public void scrollTo(int y) {
        scroller.startScroll(getScrollX(), getScrollY(), 0, y);
        // 重绘View
        invalidate();
    }

}

调用该视图代码:

scrollLayout = new ScrollLayout(this);

TextView textView = new TextView(this);
textView.setText("测试");
textView.setGravity(Gravity.CENTER);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300));
textView.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       scrollLayout.scrollTo(-150);
   }
});

scrollLayout.addView(textView);
setContentView(scrollLayout);

效果图:
这里写图片描述

看到这里又想到了一个问题,就是这个偏移的是子View,还是父View呢?
我们给 ScrollLayout 和 TextView 分别设置一个背景色,

textView.setBackgroundColor(Color.BLUE);
scrollLayout.setBackgroundColor(Color.GRAY);

再来看一下效果图:

这样就确定了Scroller控制的是childView。

好了,Scroller 的基本使用原理就是这些。时间不早了,洗洗睡吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值