Scroller相关

scrollTo/scrollBy

  • 这两个方法都是View的内部方法
  • scrollTo和scrollBy只能改变View的内容而不能改变View在布局中的位置。
  • 移动方向与笛卡尔坐标轴左右上下是相反的
  • 在滑动过程中,View内部的两个属性mscrollX和mscrollY都可以通过getScrollX和getScrollY方法获得,mscrollX就是View左边缘和View内容左边缘在水平方向的距离。同理,mscrollY就是View上边缘和View内容的上边缘的竖直方向的距离

Scroller

  • Scroller就是一个辅助类, 用来帮助进行弹性滑动。具体使用方法如下:
//在需要改动的view中
Scroller scroller = new Scroller(mContext);

//缓慢滚动到指定位置
private void smoothScrollTo(int destX, int destY){
      int scrollX = getScrollX();       //获取当前的mscrollX
      int scrolloY = getScrollY();     //获取当前的mscrollY
      int deltaX = destX - scrollX;
      int deltaY = destY - scrollY;
      mScroller.startScroll(scrollX, scrollY , deltaX, deltaY,1000);
      invalidate();
}


@override
public void computeScroll(){
      if ( mScroller.computeScrolljOffset()){
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
      }
}

上面的代码就是如何在自定义的View中添加弹性滑动的效果。在自定义的View初始化时,定义一个Scroller,然后自己添加一个private void smoothScrollTo()这样一个私有方法,用来被调用来执行滑动效果的。public void computeScroll()方法在view中本是一个空实现的方法,这个方法在view重绘时,draw方法中会被调用。那上面的代码整个逻辑流程是什么呢?让我们继续往下看。

  • Scroller的源码学习
    smoothScrollTo(int destX, int destY)方法中,整个逻辑流程如下:
  1. 我们首先利用view的getScrollX方法和getScrollY方法获取到现在view与其内容的偏移距离,
  2. 接着根据目标偏移距离和当前偏移距离的差值,得到这次目前需要进行得分位移
  3. 执行mScroller.startScroll()方法,输入参数是当前X,Y方向的偏移距离,目标的偏移距离,位移时间。下面介绍下mScroller.startScroll()方法的源码。主要功能是保存传递的几个参数。
public void startScroll(int startX, int startY,int dx,int dy,int duration){
     mMode = SCROLL_MODE;
     mFinished = false;
     mDurarion = duration;
     mStartTime = AnimationUtilesd.currentAnimationTimeMilllis();
     mStartX = startX;
     mStartY = startY;
     mFinalX = startX + dx;
     mFinalY = startY  + dy;
     mDeltaX = dx;
     mDeltaY = dy;
     mDurationReciprocal = 1.0f /(float) mDuration; 
}
  1. 调用invalidate()会导致该View重绘,View在draw()方法中会调用computeScroll()方法。
  2. computeScroll()方法,先调用mScroller.computeScrollOffset()方法,并判断其返回值。该方法的主要功能就是根据开始的坐标位移,目的坐标位移,当前的时间,总时间来确定此时此刻的位移X Y应该是多少,并赋给mCurrX和mCurrY。
    public boolean computeScrollOffset(){
          ...
          int timePassed = (int) (AnimationUtils.currentAnimationTimeMills() - mStartTime);
          
          if (timePassed < mDuration) {
                switch(mMode) {
                case SCROLL_MODE:
                      final float x = mInterpolartor.getInterpolation(timePassed * mDurationReciprocal);
                      mCurrX = mStartX + Math.round(x * mDeltaX);
                      mCurrY = mStartY + Math.round(x * mDeltaY);
                      break;
                      ......
                }
          }
          return true;         
    }
    
  3. computeScrollOffset()执行完后,在computeScroll方法中,使用scrollTo方法位移到刚刚计算出的mCurrX,mCurrY的位置上,然后调用postInvalidate()方法,再次要求重绘,再次调用draw方法,从而再次执行computeScroll( )方法让,从而能够绘制出不同时间在不同位置出现的移动画面。
    scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
    postInvalidate();
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 内容是博主照着书敲出来的,博主码字挺辛苦的,转载请注明出处,后序内容陆续会码出。 当了解了Android坐标系和触...
    Blankj阅读 11,710评论 3 60
  • 一、Android开发初体验 二、Android与MVC设计模式模型对象存储着应用的数据和业务逻辑。模型类通常用来...
    为梦想战斗阅读 4,585评论 0 3
  • 什么是View View 是 Android 中所有控件的基类。 View的位置参数 View 的位置由它的四个顶...
    acc8226阅读 5,054评论 0 7
  • 预备知识 Android屏幕区域划分我们先看一副图来了解一下Android屏幕的区域划分,如下:Android屏幕...
    小芸论阅读 12,909评论 6 44
  • 你身影如飞天蓦然跃出时光的水面仰望,你如皓月临空凝眸,你如星辰初绽你的色泽滋润我目光如玉你的弧度拨动我心绪如弦聆听...
    伊甸陨石阅读 2,187评论 0 1

友情链接更多精彩内容