Scroller概述
- scroller的作用:
作为一个developer,要有看官方文档的习惯,文档链接。
关于scroller的作用我就不叙述了,google一下有太多的介绍
案例分析
自定义一个viewgroup,在viewgroup里面有一个能滑动的view,且手指必须按在view上才能生效,松手后能缓慢的停下来;
- 分析:滑动view首先想到的是使用Scrooler(ViewDragHelper及属性动画咱先不考虑)。滑动,首先想到的是startScroll方法。
咱们来看看这个方法
startScroll(int startX, int startY, int dx, int dy)
startScroll(int startX, int startY, int dx, int dy, int duration)
这两个方法的区别就是多了个duration,即需要滑动到目的位置需要的时间,类似animation里面的duration
看源码:
public void startScroll(int startX, int startY, int dx, int dy) {
startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
}
其实最后调用的还是第二个方法,默认的滑动时间为250ms;
调用如下方法:
view.startScroll(getScroolX(), getScrollY(), -50, -50, )
代码意思为:从当前的scroolX scroolY,x轴移动50个像素,y轴移动50个像素。
- 但是我们的需求是需要松开手指后能继续滑动
所以,这里就得使用fling方法了,我们来看看fling方法的具体内容:
fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY)
Start scrolling based on a fling gesture.
由官网的解释来看,就知道了这是基于一个滑动手势的滑动
OK,这里我们需要用到另外一个计算速度的类VelocityTracker,关于使用方法请自行google
定位view的具体位置:
如果我们只是如下操作:
按下—>滑动—->抬起手指 —–>再按下—->滑动……
这类操作的话,那么我们很容易定位到view的具体位置,但是,我们需要的是在手指抬起后还能滑动,那么,此时我们怎么定位view的位置呢;这里我们就需要了解下Scroller的坐标系问题了
一般来说,对于viewgroup,我们我获取里面的子view的坐标只需要getLeft和getTop来就能知道当前view的x,y坐标。
那么Scroller的getScrollX()
,getScrollY()
和getFinalX()
,getFinalY()
,这里的获取的X和Y到底是什么呢,通过初次打印log信息,发现得到的x,y值有点莫名其妙,跟view的坐标系好像没什么关系,但是通过滑动我们来看获取的scrolllX坐标的规律,不难明白,这里获取的scrolllX和scrollY是基于你需要滑动的那个view的位置的。光说可能不好明白,有图为证:
- 到了这里,咱们就能很容易的搞定fling的状态下view的定位问题
贴上全部代码:
public class HoodleGroupView extends ViewGroup {
private PointF mDownPoint;
private RectF mChildeRectF;
private VelocityTracker velocityTracker;
private Scroller mScroller;
private int mMaxFlintVelocity, mMinFlintV