您的位置:首页 > 移动开发 > Android开发

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

2017-05-03 16:26 876 查看
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 = 0;

/**
* @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, 60, 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, 60, 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 = 0;
//帧率
private int fps = 60;
//间隔时间(毫秒),间隔时间 = 1000 / 帧率
private int interval = 0;
//启动时间,-1 表示尚未启动
private long startTime = -1;
//        /减速插值器
private DecelerateInterpolator decelerateInterpolator = null;

private int mChangeState = 0;  // 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 = 1000 / this.fps;
decelerateInterpolator = new DecelerateInterpolator();
mChangeState = 0;

if (fromX != toX && fromY == toY) {
mChangeState = 1;
} else if (fromX == toX && fromY != toY) {
mChangeState = 2;
} else if (fromX != toX && fromY != toY) {
mChangeState = 3;
}
}

@Override
public void run() {

if (mChangeState == 0) {
return;
}

//先判断是否是第一次启动,是第一次启动就记录下启动的时间戳,该值仅此一次赋值
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 currentX = fromX;
if (mChangeState == 1 || mChangeState == 3) {
int changeDistanceX = (int) ((fromX - toX) * decelerateInterpolator.getInterpolation(rate / enlargement));
currentX = fromX - changeDistanceX;
}

int currentY = fromY;
if (mChangeState == 2 || mChangeState == 3) {
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 == 1 || mChangeState == 3) {
mWindowParams.x = currentX;
}

if (mChangeState == 2 || mChangeState == 3) {
mWindowParams.y = currentY;
}

if (v.getParent() != null) {
mWindowManager.updateViewLayout(v, mWindowParams);
}

}

public void stop() {
mHandler.removeCallbacks(this);
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐