• 从源码的角度深入分析Scroller


    转载须注明出处,谢谢!http://blog.csdn.net/chdjj

    这篇文章我将从源码的角度深入分析Scroller类。在阅读的时候,建议大家打开源码对照着看,否则可能看的云里雾里。

    一.Scroller的用途


    熟悉android的同学必然对Scroller不陌生,Scroller是一个弹性滑动对象,可以制作很多酷炫的滑动效果,Lancher中的滑屏效果就有使用到Scroller。

    我们知道,View类中的scrollTo和scrollBy方法提供了滑动操作,但是这种滑动操作是瞬间完成的,就是说你为scrollTo提供终点坐标,该方法只要一调用,我们就会发现已经滚动到目的地了,这种方式很显然用户体验是不好的,因而android工程师为我们封装了Scroller类,这个类可以为View带来缓慢移动的效果

    具体使用方式通常是通过在你自定义的View中调用Scroller的startScroll并刷新视图,另外需重写computeScroll方法(刷新视图过程中会调用此方法),在该方法中调用Scroller的computeScrollOffset计算应该滚动到的位置,然后使用scrollTo滚动到该位置,再调用invalidate刷新,就可以实现滚动效果了(不了解的同学建议先去熟悉Scroller用法)。

    Scroller使用示例(代码片段):

    [java] view plaincopy在CO<wbr>DE上查看代码片派生到我的代码片

    1. public class MyView extends LinearLayout  
    2. {  
    3.     private Scroller mScroller;  
    4.     ... ...   
    5.     private void smoothScrollTo(int destX,int destY)  
    6.     {  
    7.         int scrollX = getScrollX();  
    8.         int scrollY = getScrollY();  
    9.   
    10.         int deltaX = destX-scrollX;  
    11.         int deltaY = destY-scrollY;  
    12.         mScroller.startScroll(scrollX,scrollY,deltaX, deltaY, 1000);  
    13.         invalidate();  
    14.     }  
    15.     @Override  
    16.     public void computeScroll()  
    17.     {  
    18.         if(mScroller != null)  
    19.         {  
    20.             if(mScroller.computeScrollOffset())  
    21.             {  
    22.                 scrollTo(mScroller.getCurrX(),mScroller.getCurrY());  
    23.                 Log.d(TAG,"scrollX="+getScrollX()+",scrollY="+getScrollY());  
    24.                 postInvalidate();  
    25.             }  
    26.         }  
    27.     }  
    28.       
    29.       
    30. }  

    二.ScrollTo、ScrollBy、getScrollX、getScrollY方法分析

     

    在分析Scroller源码之前,我们必须先了解ScrollTo,ScrollBy,getScrollX,getScrollY这几个方法的作用。这四个方法都是View类提供的,这点先明确。

    我们先分析getScrollX和getScrollY方法,查看源码实现:

      

  •     public final int getScrollY() {  
  •         return mScrollY;  
  •     }  
  • getScrollX和getScrollY方法返回的是mScrollX和mScrollY变量。这两个变量是什么呢?

    这里我直接告诉大家,mScrollX和mScrollY指的是视图内容相对于视图原始起始坐标的偏移量,mScrollX和mScrollY的默认值为0,因为默认是没有偏移的。另外需注意偏移量的正负问题,因为是相对视图起始坐标的,所以如果你是向右偏移那么mScrollX应该是负数,而向左偏移mScrollX为正数。再举个例子,比如你定义了一个ImageView,其左上角的坐标为(100,80),此时mScrollX和mScrollY值都为0(没有偏移),现在你要把该ImageView移到(120,100)处,也就是右下方,那么你的mScrollX应该是100-120=-20,mScrollY应该是80-100=-20,这下你该明白了吧。

    明白了这个问题,scrollBy和scrollTo也就不在话下了,我们查看源码:

    [java] view plaincopy在CO<wbr>DE上查看代码片派生到我的代码片

    1. public void scrollTo(int x, int y) {  
    2.        if (mScrollX != x || mScrollY != y) {  
    3.            int oldX = mScrollX;  
    4.            int oldY = mScrollY;  
    5.            mScrollX = x;  
    6.            mScrollY = y;  
    7.            invalidateParentCaches();  
    8.            onScrollChanged(mScrollX, mScrollY, oldX, oldY);  
    9.            if (!awakenScrollBars()) {  
    10.                postInvalidateOnAnimation();  
    11.            }  
    12.        }  
    13.    }  
    14.   
    15.    public void scrollBy(int x, int y) {  
    16.        scrollTo(mScrollX + x, mScrollY + y);  
    17.    }  

    先看scrollTo方法,它首先判断x,y方向的偏移量(即mScrollX,mScrollY)是否和传进来的偏移量(即x,y)相同,如果相同那么直接返回,否则我们将更新mScrollX和mScrollY,并且通知界面发生改变请求重绘。通过这种方式就可以实现滚动效果了,只是是瞬间移动的。再看这个scrollBy,直接调用的是scrollTo,根据参数很容易发现,这个方法的作用是在当前偏移基础上,再继续偏移(x,y)单位。需要注意的是这两个方法的参数是偏移量而不是实际位置哦!

    这里还有一点需要注意,那就是你调用一个View的scrollTo方法进行滚动时,滚动的并不是该View本身,而是该View的内容。比如你要对一个Button进行滚动的话,应该在Button外面包一个ViewGroup,然后调用ViewGroup的scrollTo方法。这一点也很重要,大家需要注意下!

    Tag:

    Freenovo 发表于2014-12-03 23:31:00 | 编辑 | 分享 0

    引用地址:

  • 相关阅读:
    OpenCV--图像特征(harris角点检测)
    pycharm处理命令行参数
    OpenCV--文档扫描OCR识别
    OpenCV--信用卡数字识别
    OpenCV--傅里叶变换
    OpenCV--直方图
    OpenCV--模板匹配
    OpenCV--图像轮廓
    OpenCV--图像金字塔
    51Nod-1288 汽油补给 ST表 贪心 模拟
  • 原文地址:https://www.cnblogs.com/freenovo/p/4469764.html
  • Copyright © 2020-2023  润新知