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

最近一直想做下拉刷新的效果,琢磨了好久,才走到通过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)的值貌似不是在同一个坐标系里面的。这个还有待进一步的分析和研究啊。

(0)

相关推荐

  • Android中TextView显示插入的图片实现方法

    本文实例讲述了Android中TextView显示插入的图片实现方法.分享给大家供大家参考,具体如下: Android系统默认给TextView插入图片提供了三种方式: 1.ImageSpan 2.Html.ImageGetter 3.TextView.setCompoundDrawables(left, top, right, bottom) 1.TextView使用ImageSpan显示图片 ImageSpan span = new ImageSpan(this, R.drawable.ic

  • Android编程显示网络上的图片实例详解

    本文实例讲述了Android编程显示网络上的图片的方法.分享给大家供大家参考,具体如下: 在Android中显示网络上的图片,需要先根据url找到图片地址,然后把该图片转化成Java的InputStream,然后把该InputStream流转化成BitMap,BitMap可以直接显示在android中的ImageView里.这就是显示网络上图片的思路,实现起来很简单.下面让我们看一下实现起来的过程. 首先在AndroidManifest.xml中给程序加上访问Internet的权限: 复制代码

  • Android仿淘宝商品浏览界面图片滚动效果

    用手机淘宝浏览商品详情时,商品图片是放在后面的,在第一个ScrollView滚动到最底下时会有提示,继续拖动才能浏览图片.仿照这个效果写一个出来并不难,只要定义一个Layout管理两个ScrollView就行了,当第一个ScrollView滑到底部时,再次向上滑动进入第二个ScrollView.效果如下: 需要注意的地方是: 1.如果是手动滑到底部需要再次按下才能继续往下滑,自动滚动到底部则不需要 2.在由上一个ScrollView滑动到下一个ScrollView的过程中多只手指相继拖动也不会导

  • Android游戏开发实践之人物移动地图的平滑滚动处理

    如图所示为程序效果动画图 地图滚动的原理 在本人之前博客的文章中介绍过人物在屏幕中的移动方式,因为之前拼的游戏地图是完全填充整个手机屏幕的,所以无需处理地图的平滑滚动.这篇文章我着重的向 大家介绍一下控制人物移动后地图滚动的处理方式.举个例子 如上图所示 比如人物向右移动,如果地图贴在屏幕左边边界 将先移动人物在地图的坐标,当人物在屏幕中超过三分之二后 则将地图向人物行走的反方向移动给玩家一种人物还在向右移动的假象,其实这时候人物只是播放向右行走的动画 在屏幕中的坐标不变 ,当地图向人物行走反方

  • android 显示gif图片实例详解

    在android中不支持gif格式的图片,但是由于我希望在我的程序中刚刚加载的时候有一个小人在跑步表示正在加载.而这个小人跑就是一个gif图片.也就是希望程序一启动时就加载gif图片.在网上查找了一些方法不知道是我使用的android的版本高(android4.4)还是什么问题就是加载不出来.最后想了一个办法加载了出来.这个办法就是将gif放在webView中让其显示. 下面是关于这个的代码: activity_prepare_fullscreen.xml文件 <RelativeLayout x

  • Android程序开发ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)

    例子中用于解析Json的Gson请自己Google下载 主Activity: package COM.Example.Main; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import COM.Example.Main.R; import COM.Example.Main.stringG

  • Android仿即刻首页垂直滚动图,炫酷到底!

    项目地址:https://github.com/JeasonWong/JikeGallery 话不多说,先上效果. 这个效果是在即刻app上看到,觉得很不错,遂仿之. 先说下我的实现思路(以上方的图片滚动为例,下方的文字实现效果类似): 自定义ViewGroup 装载两个ImageView和一个阴影View 通过一定规律交替控制两个ImageView和它们的marginTop,在onLayout()中实现 marginTop的具体值由属性动画控制,不断调用requestLayout() 接下来依

  • Android编程实现大图滚动显示的方法

    本文实例讲述了Android编程实现大图滚动显示的方法.分享给大家供大家参考,具体如下: 问题: 我有一张比较大的图片,比如长宽都是屏幕的两倍大小,我想实现的功能是首先将图片居中显示,由于图片太大显然只能显示一部分,然后可以通过拖动,实现图片的平滑滚动(既看不出来滚动刷新痕迹). 就像google地图一样,如果用mapView这个控件,那么可以在屏幕上拖动整个地图,但是由于地图信息量太大,如果一次拖动过快,那么屏幕会暂时显示出一些刷新痕迹(灰白的格子). 想使用mapView来加载已有图片,但是

  • Android组件Glide实现图片平滑滚动效果

    Glide是一款基于Android的图片加载和图片缓存组件,它可以最大性能地在Android设备上读取.解码.显示图片和视频.Glide可以将远程的图片.视频.动画图片等缓存在设备本地,便于提高用户浏览图片的流畅体验. Glide最核心的功能就是提高滚动图片列表的性能,并且Glide还能满足对远程图片的读取.改变尺寸以及展示的性能要求. Glide使用方法 最简单的示例代码如下: // For a simple view: @Override public void onCreate(Bundl

  • Android实现TextView显示HTML加图片的方法

    本文实例讲述了Android实现TextView显示HTML加图片的方法.分享给大家供大家参考,具体如下: TextView显示网络图片,我用android2.3的系统,可以显示图片出来,并且如果图片比较大,应用会卡的现象,肯定是因为使用主线程去获取网络图片造成的,但如果我用android4.0以上的系统运行,则不能显示图片,只显示小方框. 究其原因,是在4.0的系统上执行的时候报错了,异常是:Android.os.NetworkOnMainThreadException 经过查文档,原来是4.

  • 比较完整的android MP3 LRC歌词滚动高亮显示(附源码)

    1.以前的滚动只是安行来刷新,现在不是按行来滚动了,其实就是在一定时间内整体往上移动,比如说在1S内刷新10次,由于认得肉眼看起来像是滚动. 关键代码如下: 复制代码 代码如下: float plus = currentDunringTime == 0 ? 30                : 30                        + (((float) currentTime - (float) sentenctTime) / (float) currentDunringTim

  • Android实现在TextView文字过长时省略部分或滚动显示的方法

    本文实例讲述了Android实现在TextView文字过长时省略部分或滚动显示的方法.分享给大家供大家参考,具体如下: TextView中有个ellipsize属性,作用是当文字过长时,该控件该如何显示,解释如下: 1.android:ellipsize="start"-–省略号显示在开头 2.android:ellipsize="end"--省略号显示在结尾 3.android:ellipsize="middle"--省略号显示在中间 4.an

随机推荐