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 ...
随机推荐
- NOIP 2018数据点
链接: https://pan.baidu.com/s/14jXQGPSac3b9_m5h5x2wGQ 提取码: 1cbk 好文别忘点赞!!!
- bzoj5138 [Usaco2017 Dec]Push a Box
题目描述: bz luogu 题解: 暴力可以记录$AB$位置转移,这个时候状态是$n^4$的,无法接受. 考虑只记录$A$在$B$旁边时的状态,这个时候状态时$n^2$的. 所以说转移有两种,一种是 ...
- Ubuntu 18.04修改默认源
安装Ubuntu 18.04后,使用国外源太慢了,修改为国内源会快很多. 修改阿里源为Ubuntu 18.04默认的源 备份/etc/apt/sources.list #备份 cp /etc/apt/ ...
- PAT Basic 1021
1021 个位数统计 给定一个k位整数N = d~k-1~*10^k-1^ + ... + d~1~*10^1^ + d~0~ (0<=d~i~<=9, i=0,...,k-1, d~k- ...
- Mysql 学习目录
Mysql 目录 Mysql之路[第一篇]:Mysql基础 Mysql之路[第二篇]:Mysql 常用命令 Mysql之路[第三篇]:Python对Mysql的操作 Mysql之路[第四篇]:ORM ...
- Nmap手册
转自:http://drops.xmd5.com/static/drops/tips-4333.html 0x00:说明 只是一个快速查询手册,理论的东西都没有补充,欢迎大家积极在评论区补充自己常用的 ...
- appium之android_uiautomator定位进阶版
前言 上一篇介绍uiautomator的定位方式都是类似这种'new UiSelector().xxx("xxx")',看起非常长,我也记不住,这很不python.于是本篇优化了定 ...
- 在 Yii2 项目中使用 Composer 添加 FontAwesome 字体资源
2014-06-21 19:05 原文 简体 繁體 2,123 次围观 前天帮同事改个十年前的网站 bug,页面上一堆 include require 不禁让人抱头痛哭.看到 V2EX 上的讨论说,写 ...
- zoj 2830 Champion of the Swordsmanship
Champion of the Swordsmanship Time Limit: 2 Seconds Memory Limit: 65536 KB In Zhejiang Universi ...
- VOC Segmentation GT图像颜色表生成分析
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/52185581 PASCAL VOC图像 ...