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)的值貌似不是在同一个坐标系里面的。这个还有待进一步的分析和研究啊。
android开发教程之使用线程实现视图平滑滚动示例的更多相关文章
- android开发教程之使用线程实现视图平滑滚动示例 改
package com.melonsapp.messenger.ui.popupuser; import android.os.Handler; import android.view.View; i ...
- Android开发教程大全介绍
Android是由谷歌在2007年推出的一个开放系统平台,主要针对移动设备市场,目前版本为Android 4.0.Android基于Linux,开发者可以使用Java或C/C++开发Android应用 ...
- ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map
原文地址: ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NE ...
- ArcGIS Runtime for Android开发教程V2.0(4)基础篇---MapView
原文地址: ArcGIS Runtime for Android开发教程V2.0(4)基础篇---MapView - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http:/ ...
- ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置
原文地址: ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.c ...
- ArcGIS Runtime for Android开发教程V2.0(1)基本概念
原文地址: ArcGIS Runtime for Android开发教程V2.0(1)基本概念 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.csd ...
- 【Android 开发教程】动态添加Fragments
本章节翻译自<Beginning-Android-4-Application-Development>,如有翻译不当的地方,敬请指出. 原书购买地址http://www.amazon.co ...
- 收集整理Android开发所需的Android SDK、开发中用到的工具、Android开发教程、Android设计规范,免费的设计素材等。
AndroidDevTools Android Dev Tools官网地址:www.androiddevtools.cn 收集整理Android开发所需的Android SDK.开发中用到的工具.An ...
- Windows Phone 8初学者开发—第12部分:改进视图模型和示例数据
原文 Windows Phone 8初学者开发—第12部分:改进视图模型和示例数据 第12部分:改进视图模型和示例数据 原文地址:http://channel9.msdn.com/Series/Win ...
随机推荐
- PAT 乙级 1012
题目 题目地址:PAT 乙级 1012 思路 最后一个测试点怎么也过不了,问题在于A2的判断,不能单纯地以0作为判断条件:假设满足A2条件的只有两个数6和6,计算结果仍然是0,但是输出A2的值是0不是 ...
- Git学习——删除文件
怎么删除版本库中的文件呢? 首先,删除工作区中的文件:rm <file>,然后你有两个选择.其一是,真正删除版库中的文件: git rm <file> git commit - ...
- 【windows】【php】【nginx】windows 开机自启动nginx php 及nginx php配置
#启动php-nginx start-php-nginx.bat @ECHO OFFECHO Starting PHP FastCGI...RunHiddenConsole.exe php-c ...
- 爬虫cookie
Cookie Cookie 是指某些网站服务器为了辨别用户身份和进行Session跟踪,而储存在用户浏览器上的文本文件,Cookie可以保持登录信息到用户下次与服务器的会话. Cookie原理 HTT ...
- 误删除innodb ibdata数据文件-之恢复
今天在群里看到有人说不熟悉innodb把ibdata(数据文件)和ib_logfile(事务日志)文件误删除了.不知道怎么解决.当时我也不知道怎么办.后来查阅相关资料.终找到解决方法.其实恢复也挺简单 ...
- 【UOJ#51】【UR #4】元旦三侠的游戏(博弈论)
[UOJ#51][UR #4]元旦三侠的游戏(博弈论) 题面 UOJ 题解 考虑暴力,\(sg[a][b]\)记录\(sg\)函数值,显然可以从\(sg[a+1][b]\)和\(sg[a][b+1]\ ...
- 17,时间模块 time,random模块
表示时间的三种方式 在python中,通常有着三种方式来表示时间:时间戳,元祖,格式化的时间字符串: 1,时间戳(timestamp):通常来说时间戳表示的是从1970年1月1日00:00:00开始按 ...
- 优化代码,引发了早期缺陷导致新bug
早期系统有个缺陷,调用js时少提交一个参数,导致该参数一直是undefined,但是不会引起bug. 对系统进行优化后,这个参数变成了必要的,然后代码一直会走else,undefined值明显不是一个 ...
- 有关git的配置
git版本控制器总结 关于部分内容请参考:https://www.cnblogs.com/smuxiaolei/p/7484678.htmlgit是一个版本控制器,分布式管理:可以记录每次文件的改动, ...
- Luogu【P2904】跨河(DP)
题目链接在这里 此题DP.用一个前缀和一样的东西,把载i个奶牛的时间求出来,然后DP代码如下: ;i<=n;++i){ f[i]=que[i]; ;j<i;++j) f[i]=min(f[ ...