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 的基本使用原理就是这些。时间不早了,洗洗睡吧。
更多相关文章
- Android(安卓)TV native层中Canvas库的实现思路
- 探究Android(安卓)View 绘制流程,Canvas 的由来。
- Android(安卓)ServiceConnection
- Android中的getLastKnowLocation空指针异常
- Recyclview实现仿京东淘宝金刚位带滚动进度条
- Android(安卓)SurfaceFlinger 学习之路(二)----SurfaceFlinger概
- 深入探究Android定位(一)
- 如何启用Service,如何停用Service。
- Launcher 安装APK快捷方式出现在末尾空白位置