作者博客
http://www.cherylgood.cn
Scorller类官方介绍
This class encapsulates scrolling. You can use scrollers (Scroller or OverScroller) to collect the data you need to produce a scrolling animation—for example, in response to a fling gesture. Scrollers track scroll offsets for you over time, but they don’t automatically apply those positions to your view. It’s your responsibility to get and apply new coordinates at a rate that will make the scrolling animation look smooth.
这个类封装了滚动。 你可以使用scrollers(可译为滚动起)(Scroller或OverScroller)收集你需要生成的滚动动画所需要的数据,例如响应一个甩动手势。 Scrollers随着时间的推移跟踪滚动的偏移量,但不会自动将这些位置设置给你的view。 你有责任按一定的频率去获取当前滚动的坐标并应用在你的view上以使滚动动画看起来很顺滑。
示例代码:
private Scroller mScroller = new Scroller(context); … public void zoomIn() { // Revert any animation currently in progress mScroller.forceFinished(true); // Start scrolling by providing a starting point and // the distance to travel mScroller.startScroll(0, 0, 100, 0); // Invalidate to request a redraw invalidate(); }
To track the changing positions of the x/y coordinates, use computeScrollOffset(). The method returns a boolean to indicate whether the scroller is finished. If it isn’t, it means that a fling or programmatic pan operation is still in progress. You can use this method to find the current offsets of the x and y coordinates, for example:
要跟踪x / y坐标的变化位置,请使用computeScrollOffset()。 该方法返回一个布尔值以指示滚动程序是否完成。 如果还没有完成,这意味着一个甩动操作或程序化的平移操作仍在进行中。 你可以使用此方法获得x和y坐标的当前偏移量,例如:
if (mScroller.computeScrollOffset()) { // Get current x and y positions int currX = mScroller.getCurrX(); int currY = mScroller.getCurrY();... }
概要说明
Scroller提供了三个构造函数:
- Scroller(Context context) Create a Scroller with the default duration and interpolator. 使用默认的持续时间值和插值器创建一个Scroller
- Scroller(Context context, Interpolator interpolator) Create a Scroller with the specified interpolator. 使用指定的插值器创建一个Scroller,持续时间之还是默认的250
- Scroller(Context context, Interpolator interpolator, boolean flywheel) Create a Scroller with the specified interpolator.
动画效果:
- AccelerateDecelerateInterpolator: 开始和结束都是缓慢的,通过中间时候加速
- AccelerateInterpolator:先缓慢,后加速
- AnticipateInterpolator:先后退,后前进
- AnticipateOvershootInterpolator:开始后退,然后前进并超过终点位置,最终退回到终点
- BounceInterpolator:弹性衰减到结束
- CycleInterpolator:重复循环动画,速度变化遵循正弦定律
- DecelerateInterpolator:先加速,后减速
- LinearInterpolator:线性的
- OvershootInterpolator:超过终点然回来
scroller method:
- void abortAnimation() 滚到最终的x,y位置中止动画。
- boolean computeScrollOffset() 调用该方法计算,获取当前的位置。
- void extendDuration(int extends) 扩展滚动动画。
- void fling(int startX,int startY,int velocityX,int velocityY,int minX,int maxX,int minY,int maxY) 开始滚动基于一个拖拽手势。
- final void forceFinished(boolean finished) 强行停止滚动。
- float getCurrVelocity() 返回当前滚动速度。
- final int getCurrX() 返回滚动中当前的X偏移量。
- final int getCurrY() 返回滚动中当前的Y偏移量。
- final int getDuration() 返回滚动事件将花费多长时间,以毫秒为单位。
- final int getFinalX() 返回滚动结束的x坐标值。 最终int getFinalY() 返回滚动结束的y坐标值。
- final int getStartX() 返回滚动中的起始X偏移量。
- final int getStartY() 返回滚动中的起始Y偏移量。
- final boolean isFinished() 返回滚动滚轮是否完成滚动。
- void setFinalX(int newX) 设置此滚动条的最终位置(X)。
- void setFinalY(int newY) 设置此滚动条的最终位置(Y)。
- final setFriction(float friction) 设置摩擦力的摩擦量。
- void startScroll(int startX,int startY,int dx,int dy,int duration) 通过提供起点,行程距离和滚动持续时间来开始滚动。
- void startScroll(int startX,int startY,int dx,int dy) 通过提供起点和行驶距离开始滚动。
- int timePassed() 返回自滚动开始以来经过的时间。
引言
在自定义View中需要制作滚动效果的时候我们会经常遇到这个类,当然也可以通过属性动画或者补间动画实现,但是使用scroller实现有个好处,你可以中途取消滚动效果。
Scroller
官方文档也说了,Scroller负责收集滚动所需的数据,也就是说,Scroller本身并不负责“滚动”这个操作,滚动的操作是有View的scrollTo(x,y) 和scollerBy(dx,dy)这两个方法完成的。而使用Scroller实现滚动时,比如我们想让view向下滚动,此时我是一脸懵逼的,要怎么触发呢?其实Scroller需要容器类配合实现这个滚动过程,比如一个viewgroup中的childview1 想滚动,触发该滚动的并不事childview1自己,而是viewgroup触发的。如果你在TextView中使用Scroller,那么滚动时移动的其实是TextView的可视区域,TextView本身并未移动。
这个理解起来可能比较变扭,我们来借助图形理解一下:
如上图:view1从右边往左下滚动,其实内部是将viewgroup的可视区域往右移动了, 使用Scroller时,最长用的方法就是scrollTo 和ScrollBy,有关这两个方法的使用介绍和区别,网上其实有很多相关的文章。
ScrollTo(int x, int y) 我只要见过,不管你过程如何 —-滑动到(x,y)这个点,不管你怎么跑,你最后得给我滚到这个点就对了。
接下来我们来个一简单的demo实践一下:先看效果图
由于上传文件大小限制,效果图的速度是被加快了的,其实滑动是一下子就滚到一个点的,没有动画效果。这种体验是及不好的。
代码如下:
本次是让textView进行滚动
看实现代码
当点击startScrollby的时,让LinearLayout里面的textview向右滚动100px,这里为什么是-100呢,按照坐标轴来说100才是向右移动才对啊!
当时我也是一脸懵逼的,突然一想,不对,移动的并不是textview,而是linearlayout的可视区域,视觉上的textview向右滚,其实是linearlayout的可视区域向左移动,所以是-100;当点击startScrollto的时候,我们让linearlayout的可视区域回到原点。