温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在Android中使用Scroller实现一个弹性滑动效果

发布时间:2021-03-29 17:33:43 来源:亿速云 阅读:165 作者:Leah 栏目:移动开发

这期内容当中小编将会给大家带来有关怎么在Android中使用Scroller实现一个弹性滑动效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

scrollTo、scrollBy

View内部为了实现滑动提供了这两个方法,但是使用这两个方法滑动的效果是瞬间的不够平滑,如何实现View的弹性滑动呢?这正是本博文讨论的主题。另外这两个函数滑动的是View的内容不是View本身。比如对于普通View好比TextView其内容就是文本,ImageView的内容则是drawable对象,采用这两种方法滑动的时候其实分别滑动的是文本及drawable对象,对于ViewGroup采用这两种方法滑动的时候则是对其子元素的滑动。所以想要使用scrollTo、scrollBy方法实现拖动View(指的是普通的View不包含ViewGroup)的效果必须在View外面在包一层ViewGroup。

Scroller类

上面提到使用scrollTo、scrollBy来滑动View的时候是很生硬得滑过去的,不够平滑,自然用户体验也不好,因此我们要实现一个弹性的滑动。如何实现弹性滑动呢?方法有很多,但思想都是一致的,即将实现一段距离的滑动分成多次来进行,每一次滑动一小段,渐近式的滑动。本文只是介绍其中的一种即使用Scroller实现弹性滑动。以下结合实例看看Scroller是如何实现平滑滑动的呢 ?

public class SmoothScrollView extends LinearLayout{      Scroller mScroller ;    int startX;    int startY;  public SmoothScrollView(Context context, AttributeSet attrs) {    super(context, attrs);    //创建Scroller实例    mScroller = new Scroller(context);    }      public void smoothScroll(int dx,int dy,int duration){    //获取滑动起点坐标    startX = getScrollX();    startY = getScrollY();    //设置滑动参数    mScroller.startScroll(startX,startY,dx,dy,duration);    //重新绘制View    invalidate();    }    @Override  public void computeScroll() {    // TODO Auto-generated method stub    super.computeScroll();    boolean flag = mScroller.computeScrollOffset();    //递归终止条件:滑动结束    if(flag == false){      return;    }else{    //mScroller.getCurrX(),mScroller.getCurrY()记录的是此刻要滑动达到的目标坐标    scrollTo(mScroller.getCurrX(),mScroller.getCurrY());    }    //递归调用    invalidate();//或者postInvalidate()    }  }

 看到第9行,首先在SmoothScrollView内部创建一个Scroller对象,第13行的smoothScroll方法是实现SmoothScrollView的平滑滑动,可以看到实现平滑滑动首先调用第18行Scroller的startScroll方法来设置滑动参数,下文会分析这个方法,这里先放一放。然后在第20行调用invalidate方法,这个方法会导致SmoothScrollView重绘,从而调用draw方法之后又会调用computeScroll方法,在第24行可以看到这里重写了computeScroll方法,因此调用invalidate方法最终会导致computeScroll方法被调用。第27~29行调用Scroller的computeScrollOffeset方法并判断是否滑动结束,computeScrollOffset是如何判断滑动结束的呢?这里也先放一放下文在分析。如果滑动未结束,执行第33行调用scrollTo滑动SmoothScrollView至此刻目的坐标,然后递归调用invalidate方法。

以下是对Scroller几个方法的分析:

public void startScroll(int startX, int startY, int dx, int dy, int duration) {      mMode = SCROLL_MODE;      mFinished = false;      mDuration = duration;    //记录开始滑动的时间      mStartTime = AnimationUtils.currentAnimationTimeMillis();    //滑动起始横坐标      mStartX = startX;    //滑动起始纵坐标      mStartY = startY;    //滑动结束横坐标      mFinalX = startX + dx;    //滑动结束纵坐标      mFinalY = startY + dy;    //横向滑动偏移量      mDeltaX = dx;    //纵向滑动偏移量      mDeltaY = dy;    //mDuration表示的是整个滑动持续的时间      mDurationReciprocal = 1.0f / (float) mDuration;    }

从以上代码可以看到startScroll方法其实根本没有滑动View只是对滑动参数进行设置。往下再来看看computeScrollOffset方法,computeScrollOffset返回true则表示滑动还没结束返回false表示滑动结束,它的实现如下:
[java] view plain copy

public boolean computeScrollOffset() {      if (mFinished) {        return false;      }        int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);     //判断此刻是否在有效滚动周期内      if (timePassed < mDuration) {        switch (mMode) {        case SCROLL_MODE:    //当前时刻滑动偏移量所占份额          float x = (float)timePassed * mDurationReciprocal;              if (mInterpolator == null)            x = viscousFluid(x);           else            x = mInterpolator.getInterpolation(x);          //获取当前时刻要滚动到的位置          mCurrX = mStartX + Math.round(x * mDeltaX);          mCurrY = mStartY + Math.round(x * mDeltaY);          break;        case FLING_MODE:          float timePassedSeconds = timePassed / 1000.0f;          float distance = (mVelocity * timePassedSeconds)              - (mDeceleration * timePassedSeconds * timePassedSeconds / 2.0f);                    mCurrX = mStartX + Math.round(distance * mCoeffX);          // Pin to mMinX <= mCurrX <= mMaxX          mCurrX = Math.min(mCurrX, mMaxX);          mCurrX = Math.max(mCurrX, mMinX);                    mCurrY = mStartY + Math.round(distance * mCoeffY);          // 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;    }

上述就是小编为大家分享的怎么在Android中使用Scroller实现一个弹性滑动效果了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI