当前位置:  编程技术>移动开发

android开发教程之使用线程实现视图平滑滚动示例

    来源: 互联网  发布时间:2014-10-24

    本文导语:  最近一直想做下拉刷新的效果,琢磨了好久,才走到通过onTouch方法把整个视图往下拉的步骤,接下来就是能拉下来,松开手要能滑回去啊。网上看了好久,没有找到详细的下拉刷新的例子,只有自己慢慢琢磨了。昨天和今天,...

最近一直想做下拉刷新的效果,琢磨了好久,才走到通过onTouch方法把整个视图往下拉的步骤,接下来就是能拉下来,松开手要能滑回去啊。网上看了好久,没有找到详细的下拉刷新的例子,只有自己慢慢琢磨了。昨天和今天,研究了两天,下拉之后回滚回去的效果终于今天做出来了!开心。现在来分享下我的实现方法和一些心得体会吧。
我看了网上一个大神的例子,发现是在onTouch里面使用View的scrollTo(int, int)方法,来使整个视图往下滚动的,我尝试了使用setTranslationY()来对视图进行回滚,第一次是没问题的,但多滚动几次之后,整个视图实际上已经到了非常“高”的地方了,要拉很长的距离才能看到内容。所以回滚也必须使用scrollTo(int, int)方法来操作。
但scrollTo(int, int)执行是瞬间的,方法名讲是滚动到,实际上就是“瞬移到”某个位置,因此需要一步一步的去瞬移它,让它看上去是滚过去的……

因为等下要去跑步了,还有就是也没有什么很多的要点需要讲解,我就直接上代码给大家看,注释都写好了,要点会单独提一下,更详细的讲解与心得就等着我哪天把下拉刷新实现了吧。

代码如下:

/**
     * @desc    平滑滚动
     * @param    v        需要操控的视图
     * @param    fromY    起始Y坐标
     * @param    toY        终止Y坐标
     * @param    fps        帧率
     * @param    durtion    动画完成时间(毫秒)   
     * */
    private void smoothScroll(View v, int fromY, int toY, int fps, long durtion) { 
        smoothScrollThread = new SmoothScrollThread(v, fromY, toY, durtion, fps);
        smoothScrollThread.run();
    }

    /**
     * @desc    平滑滚动线程,用于递归调用自己来实现某个视图的平滑滚动
     * */
    class SmoothScrollThread implements Runnable {   
        //需要操控的视图
        private View v = null;     
        //原Y坐标
        private int fromY = 0; 
        //目标Y坐标
        private int toY = 0;     
        //动画执行时间(毫秒)
        private long durtion = 0;     
        //帧率
        private int fps = 60;      
        //间隔时间(毫秒),间隔时间 = 1000 / 帧率
        private int interval = 0;  
        //启动时间,-1 表示尚未启动
        private long startTime = -1;
        /减速插值器
        private DecelerateInterpolator decelerateInterpolator = null;

        /**
         * @desc    构造方法,做好第一次配置
         * */
        public SmoothScrollThread(View v, int fromY, int toY, long durtion, int fps) {
            this.v = v;
            this.fromY = fromY;
            this.toY = toY;
            this.durtion = durtion;
            this.fps = fps;
            this.interval = 1000 / this.fps;      
            decelerateInterpolator = new DecelerateInterpolator();
        }
        @Override
        public void run() {
            //先判断是否是第一次启动,是第一次启动就记录下启动的时间戳,该值仅此一次赋值
            if (startTime == -1) {
                startTime = System.currentTimeMillis();
            }         
            //得到当前这个瞬间的时间戳
            long currentTime = System.currentTimeMillis();     
            //放大倍数,为了扩大除法计算的浮点精度
            int enlargement = 1000;         
            //算出当前这个瞬间运行到整个动画时间的百分之多少
            float rate = (currentTime - startTime) * enlargement / durtion;          
            //这个比率不可能在 0 - 1 之间,放大了之后即是 0 - 1000 之间
            rate = Math.min(rate, 1000);          
            //将动画的进度通过插值器得出响应的比率,乘以起始与目标坐标得出当前这个瞬间,视图应该滚动的距离。
            int changeDistance = (int) ((fromY - toY) * decelerateInterpolator.getInterpolation(rate / enlargement));           
            int currentY = fromY - changeDistance;          
            v.scrollTo(0, currentY);           
            if (currentY != toY) {
                postDelayed(this, this.interval);
            } else {
                return;
            }
        }  
        public void stop() {
            removeCallbacks(this);
        }
    }

一些要点:

1.使用线程的目的是可以递归的调用自己,在每个run()方法里只滚动一点点,这个一点点根据帧率和插值器来决定。

2.插值器实际上就是一个函数(数学里的函数),输入0-1之间的浮点数,输出0-1之间的浮点数,输出的曲线是什么样的,就看是什么插值器了,decelerate就是减速插值器了,在平面直角坐标系里面,x值均匀变化,y轴的变化越来越慢。

3.放大倍数(就是那里乘以1000)是为了提高精度,因为通过实践发现用已经过的毫秒数除以整个动画周期得出的结果是0.0 -> 0.0 -> 0.0 -> 0.0 -> 1.0 -> 1.0 -> 1.0 -> 1.0 -> 1.0 -> 2.0 -> 2.0 -> 2.0,虽然是浮点数,但精度却莫名的保持在个位数上,乘以1000后,便会出现0-1000的均匀变化,这个时候去除以1000,便可得到0.000 - 1.000之间的均匀变化的数。

4.还有个很奇葩的是MotionEvent.getY()的值和scrollTo(int,int)的值貌似不是在同一个坐标系里面的。这个还有待进一步的分析和研究啊。


    
 
 

您可能感兴趣的文章:

  • Android 月视图控件 MonthView
  • Android Moveview滑屏移动视图类完整实例
  • Android开发:TextView加入滚动条示例
  • android开发教程之switch控件使用示例
  • android开启免提切换功能示例
  • Android开发之注册登录方法示例
  • 手写android布局示例
  • Android示例程序 apps-for-android
  • android网络编程之android连接网络的简单示例代码
  • android获取当前手机号示例程序
  • android读取assets文件示例
  • android读取raw文件示例
  • android实现来电静音示例(监听来电)
  • android开机自启动app示例分享
  • android开发教程之自定义控件checkbox的样式示例
  • Android创建文件实现对文件监听示例
  • android输入框与文本框加滚动条scrollview示例
  • android保存Bitmap图片到指定文件夹示例
  • android播放gif格式图片示例
  • Android获取apk程序签名信息代码示例
  • android中设置TextView/Button 走马灯(Marquee)效果示例
  • android教程使用webview访问https的url处理sslerror示例
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • android使用handler ui线程和子线程通讯更新ui示例
  • Android 在其他线程中更新UI线程的解决方法
  • Android开发笔记之:如何安全中止一个自定义线程Thread的方法
  • Handler与Android多线程详解
  • 浅析android中的线程封装
  • Android Handler主线程和一般线程通信的应用分析
  • android开发教程之子线程中更新界面
  • android使用多线程更新ui示例分享
  • android使用handlerthread创建线程示例
  • Android多线程处理机制中的Handler使用介绍
  • Android后台线程和UI线程通讯实例
  • Android提高之SurfaceView与多线程的混搭实例
  • 在Android线程池里运行代码任务实例
  • android开发教程之handle实现多线程和异步处理
  • Android中创建多线程管理器实例
  • Android开发笔记之:深入理解多线程AsyncTask
  • Android多线程及异步处理问题详细探讨
  • 深入Android线程的相关问题解惑
  • 深入Android Handler与线程间通信ITC的详解
  • android 多线程技术应用
  • 申请Android Map 的API Key(v2)的最新申请方式(SHA1密钥)
  • Android瀑布流实例 android_waterfall
  • Android开发需要的几点注意事项总结
  • Android系统自带样式 (android:theme)
  • android 4.0 托管进程介绍及优先级和回收机制
  • Android网络共享软件 Android Wifi Tether
  • Android访问与手机通讯相关类的介绍
  • Android 图标库 Android GraphView
  • Android及andriod无线网络Wifi开发的几点注意事项
  • 轻量级Android开发工具 Android Tools
  • Android 2.3 下StrictMode介绍


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3