Android的Scroller介绍

本文深入介绍了Android中的Scroller类,探讨了如何通过该类实现平滑的滚动效果,特别是通过startScroll方法设置滚动动画参数,并结合computeScrollOffset方法计算滚动过程中每一帧的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Scroller类的介绍

 

  

     

       我们知道想把一个View偏移至指定坐标(x,y)处,利用scrollTo()方法直接调用就OK了,但我们不能忽视的是,该方法本身

   来的的副作用:非常迅速的将View/ViewGroup偏移至目标点,而没有对这个偏移过程有任何控制,对用户而言可能是不太

   友好的。于是,基于这种偏移控制,Scroller类被设计出来了,该类的主要作用是为偏移过程制定一定的控制流程(后面我们会

   知道的更多),从而使偏移更流畅,更完美。

   

     可能上面说的比较悬乎,道理也没有讲透。下面我就根据特定情景帮助大家分析下:

 

        情景: 从上海如何到武汉?

            普通的人可能会想,so easy : 飞机、轮船、11路公交车...

            文艺的人可能会想,  小 case : 时空忍术(火影的招数)、翻个筋斗(孙大圣的招数)...

 

     不管怎么样,我们想出来的套路可能有两种:

               1、有个时间控制过程才能抵达(缓慢的前进)                              -----     对应于Scroller的作用

                      假设做火车,这个过程可能包括: 火车速率,花费周期等;

               2、瞬间抵达(超神太快了,都眩晕了,用户体验不太好)                     ------   对应于scrollTo()的作用

 

    模拟Scroller类的实现功能:

 

        假设从上海做动车到武汉需要10个小时,行进距离为1000km ,火车速率200/h 。采用第一种时间控制方法到达武汉的

   整个配合过程可能如下:

        我们每隔一段时间(例如1小时),计算火车应该行进的距离,然后调用scrollTo()方法,行进至该处。10小时过完后,

    我们也就达到了目的地了。

 

    相信大家心里应该有个感觉了。我们就分析下源码里去看看Scroller类的相关方法.

 

     其源代码(部分)如下: 路径位于 \frameworks\base\core\java\android\widget\Scroller.java

 

[java]  view plain copy print ?
  1. public class Scroller  {  
  2.   
  3.     private int mStartX;    //起始坐标点 ,  X轴方向  
  4.     private int mStartY;    //起始坐标点 ,  Y轴方向  
  5.     private int mCurrX;     //当前坐标点  X轴, 即调用startScroll函数后,经过一定时间所达到的值  
  6.     private int mCurrY;     //当前坐标点  Y轴, 即调用startScroll函数后,经过一定时间所达到的值  
  7.      
  8.     private float mDeltaX;  //应该继续滑动的距离, X轴方向  
  9.     private float mDeltaY;  //应该继续滑动的距离, Y轴方向  
  10.     private boolean mFinished;  //是否已经完成本次滑动操作, 如果完成则为 true  
  11.   
  12.     //构造函数  
  13.     public Scroller(Context context) {  
  14.         this(context, null);  
  15.     }  
  16.     public final boolean isFinished() {  
  17.         return mFinished;  
  18.     }  
  19.     //强制结束本次滑屏操作  
  20.     public final void forceFinished(boolean finished) {  
  21.         mFinished = finished;  
  22.     }  
  23.     public final int getCurrX() {  
  24.         return mCurrX;  
  25.     }  
  26.      /* Call this when you want to know the new location.  If it returns true, 
  27.      * the animation is not yet finished.  loc will be altered to provide the 
  28.      * new location. */    
  29.     //根据当前已经消逝的时间计算当前的坐标点,保存在mCurrX和mCurrY值中  
  30.     public boolean computeScrollOffset() {  
  31.         if (mFinished) {  //已经完成了本次动画控制,直接返回为false  
  32.             return false;  
  33.         }  
  34.         int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);  
  35.         if (timePassed < mDuration) {  
  36.             switch (mMode) {  
  37.             case SCROLL_MODE:  
  38.                 float x = (float)timePassed * mDurationReciprocal;  
  39.                 ...  
  40.                 mCurrX = mStartX + Math.round(x * mDeltaX);  
  41.                 mCurrY = mStartY + Math.round(x * mDeltaY);  
  42.                 break;  
  43.             ...  
  44.         }  
  45.         else {  
  46.             mCurrX = mFinalX;  
  47.             mCurrY = mFinalY;  
  48.             mFinished = true;  
  49.         }  
  50.         return true;  
  51.     }  
  52.     //开始一个动画控制,由(startX , startY)在duration时间内前进(dx,dy)个单位,即到达坐标为(startX+dx , startY+dy)出  
  53.     public void startScroll(int startX, int startY, int dx, int dy, int duration) {  
  54.         mFinished = false;  
  55.         mDuration = duration;  
  56.         mStartTime = AnimationUtils.currentAnimationTimeMillis();  
  57.         mStartX = startX;       mStartY = startY;  
  58.         mFinalX = startX + dx;  mFinalY = startY + dy;  
  59.         mDeltaX = dx;            mDeltaY = dy;  
  60.         ...  
  61.     }  
  62. }  

 

 

     其中比较重要的两个方法为:

 

            public void startScroll(int startX, int startY, int dx, int dy, int duration)

                   函数功能说明:根据当前已经消逝的时间计算当前的坐标点,保存在mCurrX和mCurrY值中

            public void startScroll(int startX, int startY, int dx, int dy, int duration)

                  函数功能说明:开始一个动画控制,由(startX , startY)在duration时间内前进(dx,dy)个单位,到达坐标为

                      (startX+dx , startY+dy)处。

 

        PS : 强烈建议大家看看该类的源码,便于后续理解。


知识点二: computeScroll()方法介绍

 

       为了易于控制滑屏控制,Android框架提供了 computeScroll()方法去控制这个流程。在绘制View时,会在draw()过程调用该

  方法。因此, 再配合使用Scroller实例,我们就可以获得当前应该的偏移坐标,手动使View/ViewGroup偏移至该处。

     computeScroll()方法原型如下,该方法位于ViewGroup.java类中      

 

[java]  view plain copy print ?
  1. /** 
  2.      * Called by a parent to request that a child update its values for mScrollX 
  3.      * and mScrollY if necessary. This will typically be done if the child is 
  4.      * animating a scroll using a {@link android.widget.Scroller Scroller} 
  5.      * object. 
  6.      */由父视图调用用来请求子视图根据偏移值 mScrollX,mScrollY重新绘制  
  7.     public void computeScroll() { //空方法 ,自定义ViewGroup必须实现方法体  
  8.           
  9.     }  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoqiang_0719

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值