package com.melonsapp.messenger.ui.popupuser;

import android.os.Handler;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator; import java.util.Timer; /**
* Created by lidaqiang on 17/5/3.
*/ public class SmoothScroll {
private Handler mHandler = new Handler();
SmoothScrollThread smoothScrollThread;
public static int noData = ; /**
* @param v 需要操控的视图
* @param fromX 起始Y坐标
* @param toX 终止Y坐标
* @param fps 帧率
* @param durtion 动画完成时间(毫秒)
* @desc 平滑滚动
*/
public SmoothScroll(View v, WindowManager windowManager, WindowManager.LayoutParams windowParams, int fromX, int toX, int fps, long durtion) {
this(v, windowManager, windowParams, fromX, toX, noData, noData, , durtion);
} public SmoothScroll(View v, WindowManager windowManager, WindowManager.LayoutParams windowParams, int fromX, int toX, int fromY, int toY, long durtion) {
this(v, windowManager, windowParams, fromX, toX, fromY, toY, , durtion);
} public SmoothScroll(View v, WindowManager windowManager, WindowManager.LayoutParams windowParams, int fromX, int toX, int fromY, int toY, int fps, long durtion) {
smoothScrollThread = new SmoothScrollThread(v, windowManager, windowParams, fromX, toX, fromY, toY, durtion, fps);
} public void start() {
if (smoothScrollThread == null) {
return;
}
smoothScrollThread.run();
} public void stop() {
if (smoothScrollThread == null) {
return;
}
smoothScrollThread.stop();
} /**
* @desc 平滑滚动线程,用于递归调用自己来实现某个视图的平滑滚动
*/
class SmoothScrollThread implements Runnable {
WindowManager mWindowManager;
WindowManager.LayoutParams mWindowParams;
//需要操控的视图
private View v = null;
//原X坐标
private int fromX = noData;
//目标X坐标
private int toX = noData; //原Y坐标
private int fromY = noData;
//目标Y坐标
private int toY = noData;
//动画执行时间(毫秒)
private long durtion = ;
//帧率
private int fps = ;
//间隔时间(毫秒),间隔时间 = 1000 / 帧率
private int interval = ;
//启动时间,-1 表示尚未启动
private long startTime = -;
// /减速插值器
private DecelerateInterpolator decelerateInterpolator = null; private int mChangeState = ; // 0 x,y都不变 1 x变 2 y变 3 x,y都变 /**
* @desc 构造方法,做好第一次配置
*/
public SmoothScrollThread(View v, WindowManager windowManager, WindowManager.LayoutParams windowParams, int fromX, int toX, int fromY, int toY, long durtion, int fps) {
mWindowManager = windowManager;
mWindowParams = windowParams;
this.v = v;
this.fromX = fromX;
this.toX = toX;
this.fromY = fromY;
this.toY = toY;
this.durtion = durtion;
this.fps = fps;
this.interval = / this.fps;
decelerateInterpolator = new DecelerateInterpolator();
mChangeState = ; if (fromX != toX && fromY == toY) {
mChangeState = ;
} else if (fromX == toX && fromY != toY) {
mChangeState = ;
} else if (fromX != toX && fromY != toY) {
mChangeState = ;
}
} @Override
public void run() { if (mChangeState == ) {
return;
} //先判断是否是第一次启动,是第一次启动就记录下启动的时间戳,该值仅此一次赋值
if (startTime == -) {
startTime = System.currentTimeMillis();
}
//得到当前这个瞬间的时间戳
long currentTime = System.currentTimeMillis();
//放大倍数,为了扩大除法计算的浮点精度
int enlargement = ;
//算出当前这个瞬间运行到整个动画时间的百分之多少
float rate = (currentTime - startTime) * enlargement / durtion;
//这个比率不可能在 0 - 1 之间,放大了之后即是 0 - 1000 之间
rate = Math.min(rate, );
//将动画的进度通过插值器得出响应的比率,乘以起始与目标坐标得出当前这个瞬间,视图应该滚动的距离。 int currentX = fromX;
if (mChangeState == || mChangeState == ) {
int changeDistanceX = (int) ((fromX - toX) * decelerateInterpolator.getInterpolation(rate / enlargement));
currentX = fromX - changeDistanceX;
} int currentY = fromY;
if (mChangeState == || mChangeState == ) {
int changeDistanceY = (int) ((fromY - toY) * decelerateInterpolator.getInterpolation(rate / enlargement));
currentY = fromY - changeDistanceY;
} notifyViewLayout(currentX, currentY); if (currentX != toX || currentY != toY) { mHandler.postDelayed(this, this.interval);
} else {
return;
}
} private void notifyViewLayout(int currentX, int currentY) {
// v.scrollTo(0, currentY);
if (mWindowParams == null || mWindowParams == null || v == null) {
return;
} if (mChangeState == || mChangeState == ) {
mWindowParams.x = currentX;
} if (mChangeState == || mChangeState == ) {
mWindowParams.y = currentY;
} if (v.getParent() != null) {
mWindowManager.updateViewLayout(v, mWindowParams);
} } public void stop() {
mHandler.removeCallbacks(this);
}
} }

android开发教程之使用线程实现视图平滑滚动示例 改的更多相关文章

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

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

  2. Android开发教程大全介绍

    Android是由谷歌在2007年推出的一个开放系统平台,主要针对移动设备市场,目前版本为Android 4.0.Android基于Linux,开发者可以使用Java或C/C++开发Android应用 ...

  3. ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map

    原文地址: ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NE ...

  4. ArcGIS Runtime for Android开发教程V2.0(4)基础篇---MapView

    原文地址: ArcGIS Runtime for Android开发教程V2.0(4)基础篇---MapView - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http:/ ...

  5. ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置

    原文地址: ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.c ...

  6. ArcGIS Runtime for Android开发教程V2.0(1)基本概念

    原文地址: ArcGIS Runtime for Android开发教程V2.0(1)基本概念 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.csd ...

  7. 【Android 开发教程】动态添加Fragments

    本章节翻译自<Beginning-Android-4-Application-Development>,如有翻译不当的地方,敬请指出. 原书购买地址http://www.amazon.co ...

  8. 收集整理Android开发所需的Android SDK、开发中用到的工具、Android开发教程、Android设计规范,免费的设计素材等。

    AndroidDevTools Android Dev Tools官网地址:www.androiddevtools.cn 收集整理Android开发所需的Android SDK.开发中用到的工具.An ...

  9. Windows Phone 8初学者开发—第12部分:改进视图模型和示例数据

    原文 Windows Phone 8初学者开发—第12部分:改进视图模型和示例数据 第12部分:改进视图模型和示例数据 原文地址:http://channel9.msdn.com/Series/Win ...

随机推荐

  1. PAT 乙级 1027

    题目 题目地址:PAT 乙级 1027 思路 本题需要注意两点: 1. 对于每行输出字符的循环和判断没有完全搞清楚,导致在4 * 的条件下会输出7个字符,n的结果是-3. 2. 没有考虑到小于等于0的 ...

  2. (44)zabbix报警媒介:email

    报警信息将会使用系统自带的sendmail发送,配置比较简单 配置媒介Email Administration→Media types->Click on Create media type   ...

  3. 如何用纯 CSS 创作一个雷达扫描动画

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/VdbGvr 可交互视频 ...

  4. python爬虫基础05-beautifulsoup

    HTML解析库BeautifulSoup4 本文链接:https://www.jianshu.com/p/e9255c446a77 BeautifulSoup 是一个可以从HTML或XML文件中提取数 ...

  5. 元组-tuple

    Python内置的元组数据类型:tuple tuple和list非常类似,但tuple一旦初始化就不能修改,因此它没有append(),insert()这样的方法 当定义一个tuple时,tuple的 ...

  6. python-leepcode-作用解析 - 5-27

    30 找不同 给定两个字符串 s 和 t,它们只包含小写字母. 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母. 请找出在 t 中被添加的字母. 示例: 输入: s = "a ...

  7. 阀值化 threshold

    OpenCV中的阈值(threshold)函数: threshold 的运用. C++: double threshold(InputArray src, OutputArray dst, doubl ...

  8. 【01】webpack的安装过程截图

    [05](moyu:最好安装在C盘.默认的安装地址.) []全局安装 01,首先要安装Node.js, Node.js 自带了软件包管理器 npm. 02,Webpack 需要 Node.js v0. ...

  9. rocketmq 问题

    1. 收不到消息-consumerOffset.json 信息错位 这种情况一般是,手动删除了store/commitlog目录里的数据等非常规手段造成了consumerOffset.json中记录的 ...

  10. linux下c++sleep函数

    #include <iostream> #include <unistd.h> using namespace std; int main(){ int i; ]; memse ...