Scroller 解析

Scroller 只是简单的滑动辅助类,记录滑动的距离、时间等信息。

public void startScroll(int startX, int startY, int dx, int dy, int duration) {   
      // 滑动模式分为平滑的滑动SCROLL_MODE模式,惯性滑动FLING_MODE模式
       mMode = SCROLL_MODE;   
      //是否结束
       mFinished = false;  
      // 滑动持续时间 ,如果不设置默认250ms
       mDuration = duration;  
      //滑动开始时间  
       mStartTime = AnimationUtils.currentAnimationTimeMillis();
       //滑动x初始值
       mStartX = startX;  
      //滑动y初始值 
       mStartY = startY;    
       //x最终值
       mFinalX = startX + dx;   
       //y最终值
       mFinalY = startY + dy;    
      //x改变值
       mDeltaX = dx;  
      //y改变值  
       mDeltaY = dy; 
      //单位时间比          
       mDurationReciprocal = 1.0f / (float) mDuration;
}

从这个方法可以看出只是简单的属性记录而已,没有直接对view进行操作。所以要view调用自己的重绘方法,postInvalidate();或Invalidate()
让view刷新从而调用computeScroll()方法。
我们都知道computeScroll方法一般都是如下写:

public void computeScroll() {   
        //判断有没有滑动结束
        if (mScroller.computeScrollOffset()) {        
             if (mScroller.getCurrX() == mScroller.getFinalX()) {          
                   countMoveEnd();       
             } else {            
                  int xPosition = mScroller.getCurrX();           
                  mMove += (mLast - xPosition);           
                  changeMoveAndValue();           
                  mLast = xPosition;        
            }    
      }
}

关键就在mScroller.computeScrollOffset()上,该方法实现对滑动距离数据的改变。

public boolean computeScrollOffset() {    
      //判断是否结束,结束反射false
      if (mFinished) {        
           return false;    
      }   
     //获取已经滑动的时间,当前时间减去开始时间
      int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime); 
      //已经滑动时间是否小于设置滑动总时间   
      if (timePassed < mDuration) {        
         switch (mMode) {        
         case SCROLL_MODE:    
         //根据Interpolator插值器计算在该时间段里移动的距离加上初始赋值赋值给mCurrX和mCurrY        
              final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);            
             mCurrX = mStartX + Math.round(x * mDeltaX);                                    
             mCurrY = mStartY + Math.round(x * mDeltaY);            
             break;     
        //滑动时,抬起手执行的惯性运动,通过复杂的运算获取当前的mCurrX 、mCurrY 值。
         case FLING_MODE:            
             final float t = (float) timePassed / mDuration;            
             final int index = (int) (NB_SAMPLES * t);            
             float distanceCoef = 1.f;            
             float velocityCoef = 0.f;            
             if (index < NB_SAMPLES) {                
                   final float t_inf = (float) index / NB_SAMPLES; 
                   final float t_sup = (float) (index + 1) / NB_SAMPLES;                
                   final float d_inf = SPLINE_POSITION[index];
                   final float d_sup = SPLINE_POSITION[index + 1];
                   velocityCoef = (d_sup - d_inf) / (t_sup - t_inf);
                   distanceCoef = d_inf + (t - t_inf) * velocityCoef; 
             }                       
             mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f;                        
             mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX));            
            // Pin to mMinX <= mCurrX <= mMaxX            
            mCurrX = Math.min(mCurrX, mMaxX);            
            mCurrX = Math.max(mCurrX, mMinX);
            mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY));            
           // Pin to mMinY <= mCurrY <= mMaxY            
            mCurrY = Math.min(mCurrY, mMaxY);            
            mCurrY = Math.max(mCurrY, mMinY);            
            if (mCurrX == mFinalX && mCurrY == mFinalY) { 
                   mFinished = true;            
            }            
           break;       
            }    
       }  else {     
            //如果时间到达设定时间结束。   
            mCurrX = mFinalX;        
            mCurrY = mFinalY;        
            mFinished = true;   
       }   
    return true;
}

如上面的computeScroll方法所述,调用mScroller.computeScrollOffset()修改mCurrY 以及mCurrY 的属性,然后再获取mScroller.getCurrX()的值,进行操作,其中changeMoveAndValue方法中含有postInvalidate()方法,重新绘制页面进而又调用computeScroll方法,直到mScroller.computeScrollOffset()返回false。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容

  • 作用 这个类封装了滚动操作,如帮我们处理手指抬起来时候的滑动操作。与ViewGroup的scrollTo(),sc...
    theFullHorizon阅读 3,832评论 0 1
  • 什么是View View 是 Android 中所有控件的基类。 View的位置参数 View 的位置由它的四个顶...
    acc8226阅读 1,164评论 0 7
  • Scroller是一个专门用于处理滚动效果的工具类,可能在大多数情况下,我们直接使用Scroller的场景并不多,...
    Ten_Minutes阅读 542评论 0 1
  • 一、Android开发初体验 二、Android与MVC设计模式模型对象存储着应用的数据和业务逻辑。模型类通常用来...
    为梦想战斗阅读 883评论 0 3
  • 图文|王學藝 命运似一片秋叶 秋天来了 既预示着美丽的极致 又昭然将孕育新生命的开端 生活如一片秋叶 也许飘落缝隙...
    王学艺阅读 259评论 2 6