zoukankan      html  css  js  c++  java
  • Android开发——弹性滑动的两种实现方式

    0. 前言  

    欢迎转载,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52538723

    我们在Android开发——View滑动的三种实现方式中学习了如何进行View滑动,在第一种方法,利用ScrollByScrollTo进行滑动时,滑动效果是瞬间完成的,为了更好的用户体验,有时我们需要滑动有一个渐变的过程。这就是所谓的弹性滑动。

     

    1.   延时策略

    我们解决弹性滑动的第一反应可能就是采用延时策略,通过Handler发送并接收延时消息每次接收到消息便完成一次ScrollTo操作,从而实现弹性滑动的效果。核心代码展示如下:

    public void handleMessage(Message msg) { 
      switch(mag.what){
    case SCROLL_FRACTION:{
        //if判断滑动还没有结束,结束则不再滑动和发送消息
        if(){
    //通过滑动完成比例计算该次滑动片段的位置点scrollX,scrollY
    View.scrollTo(scrollX,scrollY);
    mHandler.sendEmptyMessageDelayed(SCROLL_FRACTION, 20);
    }
    break;
    }
    default:
    break;
    }
    }
    

    上述这种利用Handler发送延时消息的方式比较简单,但是需要注意的是,由于系统的消息调度需要时间,完成这次弹性滑动的时间总是大于if条件判断为true的次数乘以20ms(延迟消息的发送时间间隔)

    因此对弹性滑动完成总时间有精确要求的使用场景下,使用延时策略是一个不太合适的选择。


    2.  Scroller的使用

    2.1  系统提供的Scroller

    利用系统提供给我们的Scroller类,我们可以很方便的实现弹性滑动。代码比较简单,都是模版化的,如下所示:

    Scroller scroller = new Scroller(mContext);
    private void smoothScrollTo(int destX, int destY){
    int distanceX = destX - getScrollX();
    int distanceY = destY - getScrollY();
    //设置500ms的弹性滑动总时长
    mScroller.startScroll(getScrollX(),getScrollY(),distanceX, distanceY, 500);
    //重绘
    invalidate();
    }
    
    //该方法为空实现,因此需要重写
    //该方法会被invalidate()方法触发执行
    @override
    public void computeScroll(){
        //判断滑动还没有结束
    if(mScroller.computeScrollOffset()){
        //通过Scroller类拿到下一步要滑动到的位置
        scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
        postInvalidate();
    }
    }
    

    这里说一下invalidate()postInvalidate()的区别

    为了UI安全,invalidate()可在主线程直接调用刷新界面,而postInvalidate()会用Handler通知UI线程重绘屏幕,因此后者适用于子线程

     

    2.2  自定义Scroller

    上面介绍了调用系统提供的Scroller的使用方法,但是Scroller类的getCurrX()computeScrollOffset()等方法都是写死的。实现的弹性滑动是先快后慢的效果。

    下面我们自行实现一个MyScroller类来完成匀速滑动的效果,同时也有助于理解系统Scroller类的实现原理。

    /*
     * Created by SEU_Calvin on 2016/09/12
     * 计算位移距离的自定义Scroller
    */
    public class MyScroll{
        private int startX;
        private int startY;
        private int distanceX;
    private int distanceY;
    private int duration;
        //开始执行动画的时间
        private long startTime;
        //判断是否动画结束
        private boolean isFinish;
        //计算当前距离
        private long currentX;
        private long currentY;
        public MyScroll(Context context) {
        }
    
        public long getCurrX() {
            return  currentX;
        }
        public long getCurrY() {
            return  currentY;
        }
    
        public void startScroll(int startX, int startY, int distanceX, int distanceY, int duration) {
            this.startX = startX;
            this.startY = startY;
            this.distanceX = distanceX;
            this.distanceY = distanceY;
    this.duration = duration;
            this.startTime = SystemClock.uptimeMillis();
            this.isFinish = false;
        }
        /*
     * Created by SEU_Calvin on 2016/09/12
    * 判断是否滑动结束并改变将要被使用的currentX/Y
    */
        public boolean computeScrollOffset() {
            if(isFinish){
                return false;
            }
            //获得startTime到调用由于重绘导致computeScrollOffset()调用之间的passtime
            long passtime = SystemClock.uptimeMillis()-startTime;
            //计算currentX的值,指导下一步ScrollTo的位置
    //startX/Y <currentX/Y<= startX/Y + distanceX/Y
            if(passtime<duration){
                currentX = startX + distanceX*passtime/duration;
    currentY = startY + distanceY*passtime/duration;
            }else{
                //运行结束
                currentX = startX + distanceX;
    currentY = startY + distanceY;
                isFinish = true;
            }
            return  true;
        }
    }
    

    我们只要在调用时改变调用的MyScroll类即可。其他代码不做修改。

    具体滑动效果,如匀速,匀加速,先慢后快等效果完全可以由MyScroll中自己的算法来决定


    以上就是对Android开发中弹性滑动的介绍。

    转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52538723


  • 相关阅读:
    ixgb 中断
    libvirt
    docker 查看虚拟机xml
    什么是可串行化MVCC
    算法题:实现 strStr()函数
    Python库 numpy基础内容学习笔记
    python3.6+torch1.2实现Sentiment Analysis(数据集MR)
    人工智能能力提升指导总结
    深度学习入门篇01(Tensorflow-gpu的安装)
    走进PEP8——代码规范
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461514.html
Copyright © 2011-2022 走看看