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 的基本使用原理就是这些。时间不早了,洗洗睡吧。

更多相关文章

  1. Android(安卓)TV native层中Canvas库的实现思路
  2. 探究Android(安卓)View 绘制流程,Canvas 的由来。
  3. Android(安卓)ServiceConnection
  4. Android中的getLastKnowLocation空指针异常
  5. Recyclview实现仿京东淘宝金刚位带滚动进度条
  6. Android(安卓)SurfaceFlinger 学习之路(二)----SurfaceFlinger概
  7. 深入探究Android定位(一)
  8. 如何启用Service,如何停用Service。
  9. Launcher 安装APK快捷方式出现在末尾空白位置

随机推荐

  1. android 模拟抢红包 原理
  2. EditText属性详解
  3. 探讨android图片资源的抖动处理和格式转
  4. 【Android 应用开发】 Ubuntu 安装 Andro
  5. Android 虚拟机安装SD卡
  6. Ubuntu 10.10 编译Android 2.2
  7. [置顶] 我的Android进阶之旅------>andro
  8. Android SnackBar
  9. Android——多语言适配
  10. Android assets文件夹之位置放置和作用( A