Android开发之Scroller的使用详解

其实关于Scroller这篇文章我早就想写了,起初是因为看Xlistview的源码,接触到了Scroller的使用,之后又在网上读了大量的文章,之后自己写了一个demo,对scroller也算是有了自己的看法。

我学习的道路是曲折的,所以我要把我会的东西写出来,说不定对别人就有用呢!

一、Scroller简介

先通过源码里的注释看下Scroller是做什么用的

/** * <p>This class encapsulates scrolling. You can use scrollers ({@link Scroller} * or {@link 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.</p> * * <p>Here is a simple example:</p> * * <pre> 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(); * }</pre> * * <p>To track the changing positions of the x/y coordinates, use * {@link #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:</p> * * <pre>if (mScroller.computeScrollOffset()) { *// Get current x and y positions *int currX = mScroller.getCurrX(); *int currY = mScroller.getCurrY(); * … * }</pre> */我做个简单的翻译,Scroller这个类对滑动进行了封装,你可以通过Scroller来收集一些用来执行滑动动画的数据——举个例子,为了响应fling手势,,Scrollers会跟随时间来追踪滑动的偏移,但是它们不会自动地在你的view上应用这些位置。获取并且以一个能够使滑动动画看起来流畅的速度来使用位置,这些都是由你来完成的。

mScroller,forceFinished(true);//让所有正在进行的动画都恢复原状,也就是停用所有动画

mScroller.startScroll(0,0,100,0);//前两个参数是起始坐标点,后两个分别是x,y轴要滑动的距离。

invalidate();//请求重新绘制界面,从而触发滑动

使用computeScrollOffset方法来追踪x/y轴的坐标,如果这个方法返回false,表示滑动还没有结束,我们可以通过这个方法来找到当前滑动的x和y的坐标,就像这样:

if(mScroller.computeScrollOffset()){

//获取当前x和y的坐标

int currX = mScroller.getCurrX(); int currY = mScroller.getCurrY();

}

好了,大致就是说,Scoller并不是真的能开始滑动效果的,它只是能够记录滑动动画所需要的实时数据,具体滑动动画还是得由你自己来实现的。说白了,使用Scroller类是为了给做出一个流畅的动画,而不是pia一下,还没开始就已经结束了。

二、computeScroll()介绍

/*** Called by a parent to request that a child update its values for mScrollX* and mScrollY if necessary. This will typically be done if the child is* animating a scroll using a {@link android.widget.Scroller Scroller}* object.*/public void computeScroll() {}这个方法是被parent调用的,child会根据需要来更新它的值,例如mScrollX和mScrollY,如果child在用Scroller做滚动动画的话,这个方法通常会被执行。

为了实现偏移控制,一般自定义View/ViewGroup都需要重载该方法 。

接下来看看这个方法是怎么调用的

invaliate()会导致界面重绘,上面说过invalidate方法会触发滑动动画。而有经验的朋友都知道,invalidate方法其实会引起界面重绘,所以我们从界面绘制说起,View的绘制包括三个主要过程,分别是measure,layout和draw。下面我们看View类的draw方法源码:

public void draw(Canvas canvas) {   … …  /*  * Draw traversal performs several drawing steps which must be executed  * in the appropriate order:  *  *1. Draw the background  *2. If necessary, save the canvas' layers to prepare for fading  *3. Draw view's content  *4. Draw children  *5. If necessary, draw the fading edges and restore layers  *6. Draw decorations (scrollbars for instance)  */  // Step 1, draw the background, if needed  int saveCount;  if (!dirtyOpaque) {  drawBackground(canvas);  }  … …  // Step 2, save the canvas' layers  … …  // Step 3, draw the content  if (!dirtyOpaque) onDraw(canvas);  // Step 4, draw the children  dispatchDraw(canvas);  // Step 5, draw the fade effect and restore layers  … …  }draw方法将界面绘制分成了六步,其中第三步是调用onDraw去绘制内容,第四步则是调用dispatchDraw去绘制子视图。我们再看下dispatchDraw方法: @Overrideprotected void dispatchDraw(Canvas canvas){…for (int i = 0; i < count; i++) {final View child = children[getChildDrawingOrder(count, i)];if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {more |= drawChild(canvas, child, drawingTime);}}}最后再看drawChild的源码 protected boolean drawChild(Canvas canvas, View child, long drawingTime) {…child.computeScroll();…} 人生就像一杯没有加糖的咖啡,喝起来是苦涩的,

Android开发之Scroller的使用详解

相关文章:

你感兴趣的文章:

标签云: