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. 玩转ApplicationContextAware

    当一个类实现了这个接口之后,这个类就可以方便地获得 ApplicationContext 中的所有bean.换句话说,就是这个类可以直接获取Spring配置文件中,所有有引用到的bean对象.结合工厂 ...

  2. (64)zabbix正则表达式应用

    概述 在前面的<zabbix low-level discovery>一文中有filter一项,用于从结果中筛选出你想要的结果,比如我们在filter中填入^ext|^reiserfs则表 ...

  3. H5移动端触摸事件:touchstart、touchend、touchmove

    第一部分代码事例: <html><head> <meta charset="utf-8"> <style> #main,#main1 ...

  4. jQuery实现Ajax

    jQuery.ajax([settings]) type:类型,“POST”或“GET”,默认为GET url:发送地址 data:连同请求发送到服务器的数据 dataType:预期服务器返回的数据类 ...

  5. 【php】关于尾部去除和分号问题

    One thing to remember is, if you decide to omit the closing PHP tag, then the last line of the file ...

  6. 在ubuntu上安装npm

    sudo apt install npm 执行上面的安装命令,会报错: Reading package lists... Done Building dependency tree Reading s ...

  7. 九度oj 题目1491:求1和2的个数

    题目描述: 给定正整数N,函数F(N)表示小于等于N的自然数中1和2的个数之和,例如:1,2,3,4,5,6,7,8,9,10序列中1和2的个数之和为3,因此F(10)=3.输入N,求F(N)的值,1 ...

  8. python 字典 key 和value 互换

    这里是一个可能有用的通过字典解析实现的小技巧: 交换字典的键和值. >>> a_dict = {'a': 1, 'b': 2, 'c': 3} >>> {value ...

  9. 【bzoj4868】[Shoi2017]期末考试 前缀和+暴力

    题目描述 有n位同学,每位同学都参加了全部的m门课程的期末考试,都在焦急的等待成绩的公布.第i位同学希望在第ti天或之前得知所.有.课程的成绩.如果在第ti天,有至少一门课程的成绩没有公布,他就会等待 ...

  10. 什么是JNI?

    JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C和C++)