android中view的滑动是渐变的,用得比较多的弹性滑动是以下三种:
1. Scroller;
2. Handler#postDelayed;
3. Thread#sleep;

我们现在自定义一个类AutoScrollTextView,需求是传入x移动的距离,当调用它时,这个view水平渐变滑动。

class AutoScrollTextView extends View{    Scroller scroller = new Scroller(context);    public void smoothScrollTo(int destX,int duration){        int scrollX = this.getScrollX();        int deltaX = destX - scrollX;        //表示在duration时间内水平滑动deltaX的距离        scroller.start(scrollX,0,deltaX,0,duration);        this.invalidate();    }    //通过看View的源码,知道View的computeScroll()是空的,这就需要重写我们View中的方法computeScroll()    @override    public void computeScroll(){        if(scroller.computeScrollOffSet()){                     this.scrollTo(scroller.getCurrentX(),scroller.getCurrentY());            postInvalidate();        }    }    //同理,通过看View的源码,知道View的ondraw()是空的,这就需要我们重新    @override    protected void onDraw(){    super.onDraw();    computeScroll();    }}

从上面看到,我们调用了Scroller的start(),但又调用了View的invalidate(),那里面的具体操作是什么呢?我们来看下scroller这个start()的源码:

public void startScroll(int startX,int startY,int destX,int destY,int duration){    mMode =  SCROLL_MODE;    mFinished = false;    mDuration = duration;    mStartTime = AnimationUtils.currentAnimationTimeMills();    mStartX = startX;    mStartY = startY;    mFinalX = destX + startX;    mFinalY = destY + startY;    mDeltaX = destX;    mDeltaY = destY;    mDurationReciprocal = 1.0f/(float)mDuration;}

我们扯淡的发现,在Scroller的start()方法中,并没有我们期待的滑动操作,只是对一些参数进行了定义~
由此看到,Scroller并不能让view滑动,它只是跟view配合。当在smoothScrollTo()中调用view的invalidate()方法时,就会去调用view的ondraw()方法,而在ondraw()中又不断去调用computeScroll(),而这个computeScroll()在条件允许的情况下,又会不断去调用postInvalidate()方法,如此循环往复,直到条件不允许时,动画也就结束了!
再看下判断条件scroller.computeScrollOffSet()中做了什么:

public boolean computeScrollOffSet(){    int timePassed = (int)AnimationUtils.currentAnimationTimeMills()-mStartTime;    if(timePassed < mDuration){        switch(mMode){        case SCROLL_MODE:        final float x = mInterpolator.getInterpolation(timePassed*mDurationReciprocal);        mCurrentX = mStartX + Math.round(x * mDeltaX);        mCurrentY = mStartY = Math.round(y * mDeltaY);        break;        }    }

从这里可得知,判断动画是否完成的标志,是mDuration和timePassed的相差值。
Scroller工作原理总结:
Scroller本身并不能实现view的滑动,它需要配合View的computeScroll方法才能完成弹性滑动的效果。它不断让view重绘,而在不断重绘过程中产生一个时间间隔,根据这个时间间隔能得到这个view当前的滑动位置,知道了滑动位置,就可以通过view的scrollTo方法来实现view的滑动。多次的小幅度滑动,就组成了弹性滑动。

更多相关文章

  1. 【Android】从无到有:手把手一步步教你使用最简单的 Fragment(一)
  2. Android中AppWidget加载流程(一)
  3. Android(安卓)Binder机制 - interface_cast和asBinder源码分析
  4. 设置Activity全屏
  5. Android(安卓)Test 基础知识
  6. Android(安卓)自定义view(二) 如何实现自定义组件
  7. android中处理json最佳方法
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android(安卓)原生SQLite数据库操作实战
  2. 线程池的封装和使用(二)
  3. Android(安卓)phonegap_2.8.1开发部署
  4. Android(安卓)加载富文本
  5. android获得系统时间(Handler)
  6. android Gide加载webp图片方法
  7. Android(安卓)eMMC Booting
  8. Android(安卓)项目源码大全
  9. 给两到五年经验的Android面试者
  10. android 内存缓冲机制:MemoryCache