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. Life is short.,You need Python

    真棒Python  https://awesome-python.com/ 精选的Python框架,库,软件和资源的精选列表. 灵感来自awesome-php. 真棒Python 管理员面板 算法和设 ...

  2. (4)zabbix监控第一台服务器

    2. zabbix监控服务器 创建主机,选择模板以及录入基本信息,过一分钟左右,就可以看到cpu.内存.硬盘等等使用情况.本节以图文为主.by the way, zabbix中文翻译很烂,config ...

  3. Git学习——删除文件

    怎么删除版本库中的文件呢? 首先,删除工作区中的文件:rm <file>,然后你有两个选择.其一是,真正删除版库中的文件: git rm <file> git commit - ...

  4. Python中单元测试出错了,会怎么样?

    在上一篇中,我们看到了单元测试正常通过时的情况,如果我们边修改一下要测试的函数,然后再运行单元测试,会出现什么情况. 原say_hello_name.py def hello_name(name): ...

  5. Verilog学习笔记基本语法篇(六)········ 循环语句

    在Verilog中存在着4种类型的循环语句,用来控制执行语句的执行次数. 1)forever语句: 连续执行的语句. 2)repeat语句:  连续执行n次的语句. 3)while语句:    执行语 ...

  6. PAT Basic 1069

    1069 微博转发抽奖 小明 PAT 考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔 N 个人就发出一个红包.请你编写程序帮助他确定中奖名单. 输入格式: 输入第一行给出三个正整 ...

  7. PAT Basic 1052

    1052 卖个萌 萌萌哒表情符号通常由“手”.“眼”.“口”三个主要部分组成.简单起见,我们假设一个表情符号是按下列格式输出的: [左手]([左眼][口][右眼])[右手] 现给出可选用的符号集合,请 ...

  8. STM32F407 I2C 个人笔记

    源代码;https://github.com/YuQiao0303/STM32F407-Examples/tree/master/24.IIC 概述 I2C (IIC, Inter-Integrate ...

  9. 2011 Michigan Invitational Programming Contest

    Crossings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463 Description ...

  10. POJ 1971-Parallelogram Counting,暴力1063ms!

    Parallelogram Counting 刚学hash还不会用,看到5000ms的时限于是想着暴力来一发应该可以过.以前做过类似的题,求平行四边形个数,好像是在CF上做的,但忘了时限是多少了,方法 ...