|
|
@@ -1,239 +0,0 @@
|
|
|
-package com.sheep.jiuyan.samllsheep.page.view;
|
|
|
-
|
|
|
-import android.animation.Animator;
|
|
|
-import android.animation.AnimatorListenerAdapter;
|
|
|
-import android.animation.ObjectAnimator;
|
|
|
-import android.animation.ValueAnimator;
|
|
|
-import android.os.Handler;
|
|
|
-import android.os.Message;
|
|
|
-import android.util.Log;
|
|
|
-import android.view.View;
|
|
|
-import android.view.animation.DecelerateInterpolator;
|
|
|
-import android.widget.ProgressBar;
|
|
|
-import android.widget.RelativeLayout;
|
|
|
-
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
-
|
|
|
-/**
|
|
|
- * Created by 林冠宏 on 2016/7/11.
|
|
|
- *
|
|
|
- * 真正的仿微信网页打开的进度条
|
|
|
- *
|
|
|
- * 两种方式
|
|
|
- * 1,setLayoutParams 的形式
|
|
|
- * 2,动画形式(推荐)
|
|
|
- *
|
|
|
- * 下面的所有属性都可以自己采用 get set 来自定义
|
|
|
- *
|
|
|
- */
|
|
|
-
|
|
|
-public class SlowlyProgressBar {
|
|
|
-
|
|
|
- private static final int StartAnimation = 0x12;
|
|
|
-
|
|
|
- private Handler handler;
|
|
|
- private View view;
|
|
|
- private ProgressBar progressBar;
|
|
|
-
|
|
|
- /** 当前的位移距离和速度 */
|
|
|
- private int thisWidth = 0;
|
|
|
- private int thisSpeed = 0;
|
|
|
-
|
|
|
- private int progress = 0; /** 当前的进度长度 */
|
|
|
- private int record = 0; /** 移动单位 */
|
|
|
- private int width = 10; /** 10dp each time */
|
|
|
- private int height = 3; /** 3dp */
|
|
|
-
|
|
|
- private boolean isStart = false;
|
|
|
-
|
|
|
- private int phoneWidth = 0; /** 屏幕宽度 */
|
|
|
- private int i = 0;
|
|
|
-
|
|
|
- /** 每次的移动记录容器,位移对应每帧时间 */
|
|
|
- private List<Integer> progressQuery = new ArrayList<>();
|
|
|
- private List<Integer> speedQuery = new ArrayList<>();
|
|
|
-
|
|
|
- /** 第一种 */
|
|
|
- public SlowlyProgressBar(View view, int phoneWidth) {
|
|
|
- initHandler();
|
|
|
- this.phoneWidth = phoneWidth;
|
|
|
- this.view = view;
|
|
|
- }
|
|
|
-
|
|
|
- /** 第二种 */
|
|
|
- public SlowlyProgressBar(ProgressBar progressBar) {
|
|
|
- this.progressBar = progressBar;
|
|
|
- }
|
|
|
-
|
|
|
- /** 善后工作,释放引用的持有,方能 gc 生效 */
|
|
|
- public void destroy(){
|
|
|
- if(progressQuery!=null){
|
|
|
- progressQuery.clear();
|
|
|
- progressQuery = null;
|
|
|
- }
|
|
|
- if(speedQuery!=null){
|
|
|
- speedQuery.clear();
|
|
|
- speedQuery = null;
|
|
|
- }
|
|
|
- view = null;
|
|
|
- if(handler!=null){
|
|
|
- handler.removeCallbacksAndMessages(null);
|
|
|
- handler = null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /** -------------------------------------------第二种方法-------------------------------------- */
|
|
|
- /** 在 WebViewClient onPageStarted 调用 */
|
|
|
- public void onProgressStart(){
|
|
|
- progressBar.setVisibility(View.VISIBLE);
|
|
|
- progressBar.setAlpha(1.0f);
|
|
|
- }
|
|
|
-
|
|
|
- /** 在 WebChromeClient onProgressChange 调用 */
|
|
|
- public void onProgressChange(
|
|
|
- int newProgress
|
|
|
- ){
|
|
|
- int currentProgress = progressBar.getProgress();
|
|
|
- if (newProgress >= 100 && !isStart) {
|
|
|
- /** 防止调用多次动画 */
|
|
|
- isStart = true;
|
|
|
- progressBar.setProgress(newProgress);
|
|
|
- /** 开启属性动画让进度条平滑消失*/
|
|
|
- startDismissAnimation(progressBar.getProgress());
|
|
|
- } else {
|
|
|
- /** 开启属性动画让进度条平滑递增 */
|
|
|
- startProgressAnimation(newProgress,currentProgress);
|
|
|
- }
|
|
|
- }
|
|
|
- /** -------------------------------第二种结束---------------------------- */
|
|
|
-
|
|
|
- public void setProgress(int progress){
|
|
|
- if(progress>100 || progress <= 0){ /** 不能超过100 */
|
|
|
- return;
|
|
|
- }
|
|
|
- /** 每次传入的 width 应该是包含之前的数值,所以下面要减去 */
|
|
|
- /** 下面记得转化比例,公式 (屏幕宽度 * progress / 100) */
|
|
|
- this.width = (progress * phoneWidth)/100;
|
|
|
-
|
|
|
- /** lp.width 总是获取前一次的 大小 */
|
|
|
- /** 移动 100px 时的速度一次倍率 是 2 */
|
|
|
- int size = progressQuery.size();
|
|
|
- if(size != 0){
|
|
|
- size = progressQuery.get(size-1);
|
|
|
- }
|
|
|
- Log.d("zzzzz","width - size = "+(width - size));
|
|
|
- /** 计算倍率,2/100 = x/width */
|
|
|
- int distance = width - size;
|
|
|
- int speedTime;
|
|
|
- if(distance<=100){
|
|
|
- speedTime = 2;
|
|
|
- }else{
|
|
|
- speedTime = (int) ((2 * distance)/100.0);
|
|
|
- }
|
|
|
- /** 添加 */
|
|
|
- progressQuery.add(this.width);
|
|
|
- speedQuery.add(speedTime);
|
|
|
- /** 开始 */
|
|
|
- if(!isStart){
|
|
|
- isStart = true;
|
|
|
- handler.sendEmptyMessage(StartAnimation);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public SlowlyProgressBar setViewHeight(int height){
|
|
|
- this.height = height;
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- private void initHandler(){
|
|
|
- handler = new Handler(){
|
|
|
- @Override
|
|
|
- public void handleMessage(Message msg) {
|
|
|
- super.handleMessage(msg);
|
|
|
- switch (msg.what){
|
|
|
- case StartAnimation:
|
|
|
- /** 提取队列信息 */
|
|
|
- if(progress >= thisWidth){ /** 如果已经跑完,那么移出 */
|
|
|
- if(progressQuery.size() == i){
|
|
|
- Log.d("zzzzz","break");
|
|
|
- if(progress >= 100){ /** 全部走完,隐藏进度条 */
|
|
|
- view.setVisibility(View.INVISIBLE);
|
|
|
- }
|
|
|
- isStart = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- Log.d("zzzzz", "size is " + progressQuery.size());
|
|
|
- thisWidth = progressQuery.get(i);
|
|
|
- thisSpeed = speedQuery.get(i);
|
|
|
- i ++;
|
|
|
- }
|
|
|
- move(thisSpeed,view.getLayoutParams().width);
|
|
|
- Log.d("zzzzz", "send 100 "+thisSpeed);
|
|
|
- /** 发信息的延时长度并不会影响速度 */
|
|
|
- handler.sendEmptyMessageDelayed(StartAnimation,1);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- /** 移动 */
|
|
|
- private void move(int speedTime,int lastWidth){
|
|
|
- if(speedTime > 9){
|
|
|
- speedTime = 9; /** 控制最大倍率 */
|
|
|
- }
|
|
|
- /** 乘 3 是纠正误差 */
|
|
|
- /** 原因是:px 和 db 不是对比的,个人十分建议不乘3,采用函数适配转换,下面提供个函数 */
|
|
|
- progress = (record * speedTime);
|
|
|
- /** 纠正 */
|
|
|
- if(progress >= lastWidth){
|
|
|
- view.setLayoutParams(new RelativeLayout.LayoutParams(progress,height*3));
|
|
|
- }else{
|
|
|
- Log.d("zzzzz","hit "+progress+"---"+lastWidth);
|
|
|
- }
|
|
|
- record ++;
|
|
|
- }
|
|
|
-
|
|
|
- /** 下面是动画的形式 */
|
|
|
- /**
|
|
|
- * progressBar 进度缓慢递增,300ms/次
|
|
|
- */
|
|
|
- private void startProgressAnimation(int newProgress,int currentProgress) {
|
|
|
- ObjectAnimator animator = ObjectAnimator.ofInt(progressBar, "progress", currentProgress, newProgress);
|
|
|
- animator.setDuration(300);
|
|
|
- animator.setInterpolator(new DecelerateInterpolator()); /** 减速形式的加速器,个人喜好 */
|
|
|
- animator.start();
|
|
|
- }
|
|
|
-
|
|
|
- private void startDismissAnimation(final int progress) {
|
|
|
- ObjectAnimator anim = ObjectAnimator.ofFloat(progressBar, "alpha", 1.0f, 0.0f);
|
|
|
- anim.setDuration(1500); // 动画时长
|
|
|
- anim.setInterpolator(new DecelerateInterpolator()); // 减速
|
|
|
-
|
|
|
- anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
|
|
|
- float fraction = valueAnimator.getAnimatedFraction(); // 0.0f ~ 1.0f
|
|
|
- int offset = 100 - progress;
|
|
|
- progressBar.setProgress((int) (progress + offset * fraction));
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- anim.addListener(new AnimatorListenerAdapter() {
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onAnimationEnd(Animator animation) {
|
|
|
- progressBar.setProgress(0);
|
|
|
- progressBar.setVisibility(View.GONE);
|
|
|
- isStart = false;
|
|
|
- }
|
|
|
- });
|
|
|
- anim.start();
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|