Android开发之模仿微信打开网页的进度条效果(高仿)

一,为什么说是真正的高仿?

  阐述这个问题前,先说下之前网上的,各位可以复制这段字,去百度一下  "仿微信打开网页的进度条效果" ,你会看到有很多类似的文章,不过他们有个共同点,就是实现方法都是一样的,而且,都忽略了微信加载网页时,进度条的缓慢动画效果,它不是生硬地一滑而过,而是用户体验很好,有个速度的变化,由慢到快的效果,语言难于描述,相信各位都有下载微信,可以随便打开个公众号的文章看看效果。

  好了,上面说到,之前网上的方法都是都忽略了微信加载网页时,进度条的缓慢动画效果,实现代码也是千篇一律,如下:

/** 先实例化个进度条 */
ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.ProgressBar);
/** 再实例化个 webView */
WebView webView = (WebView) findViewById(R.id.webview);
/** 然后就直接在 webClient 回调函数里面set 进度,这样的做法是生硬的效果 */
webView.setWebChromeClient(new WebChromeClient(){
 @Override
 public void onProgressChanged(WebView view, int newProgress) {
 super.onProgressChanged(view, newProgress);
 mProgressBar.setProgress(newProgress);
 }
});
/** 其他是颜色样式等,不是重点 */
.....

  我以为是 ProgressBar 控件可能自身提供了动画的 API,可惜,没有,故自己动手写了这个,你如果找到了,告诉下我。

二,为什么要搞缓慢效果?

  对,为什么要这么麻烦,你如果要搞个网页加载进度条,上面的代码不过 10 行,妥妥地实现了。因为用户体验,我不是产品经理,我是个程序员,而且这个效果也不是有谁叫我这样去做的,我就是看着别扭,微信的成功,我相信不仅仅是个朋友圈那么简单!

  程序员应该具备注重用户体验的想法。

三,我的实现思路

  方法很多,这话我说在前面,我的这种肯定不是最好的,但不失一用或改进。

  主要是通过改变 view 的 LayoutParam 来实现有不同速度的移动效果,在每一次的进度段,例如第一次0~24,第二次24~56,这就是两个进度段,这两个进度段,具有不同的速度,这个需要计算出来,先根据手机屏幕宽度和 0~100 的进度数值来等比计算出实际的宽度,再计算出移动的速度,计算出来每个进度段的数据后,讲它们放进一个列表容器里面,然后通过一个 handler 来循环提取同期数据,不断地发消息,不停地 setLayoutParam。在达到 100 后,就证明加载完毕。

  在这个过程需要处理计算的误差,例如第一个加载 20,第二次24,24-20 = 4,4/100,程序里面是 0 ,如果计算速度的话,就会差生0,所以要稍微加个 if 判断。

四,代码,内涵注释

  核心类:

package com.slowlyprogressbar;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by 林冠宏 on 2016/7/11.
 *
 * 真正的仿微信网页打开的进度条
 *
 * 下面的所有属性都可以自己采用 get set 来自定义
 *
 */
public class SlowlyProgressBar {
 private static final int StartAnimation = 0x12;
 private Handler handler;
 private View view;
 /** 当前的位移距离和速度 */
 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;
 }
 /** 善后工作,释放引用的持有,方能 gc 生效 */
 public void destroy(){
 if(progressQuery!=null){
 progressQuery.clear();
 progressQuery = null;
 }
 if(speedQuery!=null){
 speedQuery.clear();
 speedQuery = null;
 }
 view = null;
 handler.removeCallbacksAndMessages(null);
 handler = null;
 }
 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 是纠正误差 */
 progress = (record * speedTime);
 /** 纠正 */
 if(progress >= lastWidth){
 view.setLayoutParams(new RelativeLayout.LayoutParams(progress,height*3));
 }else{
 Log.d("zzzzz","hit "+progress+"---"+lastWidth);
 }
 record ++;
 }
}

五,使用方法与截图

  超简单引入,view 可以是随便一个,例如 TextView,给它一个 background 就行了,就有颜色了。

public class MainActivity extends AppCompatActivity {
 private SlowlyProgressBar slowlyProgressBar;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 slowlyProgressBar =
 new SlowlyProgressBar
  (
  findViewById(R.id.p),
  getWindowManager().getDefaultDisplay().getWidth()
  )
 .setViewHeight(3);
 WebView webView = (WebView) findViewById(R.id.webview);
 webView.setWebChromeClient(new WebChromeClient(){
 @Override
 public void onProgressChanged(WebView view, int newProgress) {
 super.onProgressChanged(view, newProgress);
 slowlyProgressBar.setProgress(newProgress);
 }
 });
 webView.loadUrl("http://www.cnblogs.com/linguanh");
 }
 @Override
 public void finish() {
 super.finish();
 if(slowlyProgressBar!=null){
 slowlyProgressBar.destroy();
 slowlyProgressBar = null;
 }
 }
} 

以上所述是小编给大家介绍的Android开发之模仿微信打开网页的进度条效果(高仿),如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

时间: 2016-07-10

Android自定义view实现水波纹进度球效果

今天我们要实现的这个view没有太多交互性的view,所以就继承view. 自定义view的套路,套路很深 1.获取我们自定义属性attrs(可省略) 2.重写onMeasure方法,计算控件的宽和高 3.重写onDraw方法,绘制我们的控件 这么看来,自定义view的套路很清晰嘛. 我们看下今天的效果图,其中一个是放慢的效果(时间调的长) 我们按照套路来. 一.自定义属性 <declare-styleable name="WaveProgressView"> <at

Android控件之ToggleButton的使用方法

ToggleButton的状态只能是选中和未选中,并且需要为不同的状态设置不同的显示文本. 以下案例为ToggleButton的用法 目录结构 main.xml布局文件 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    androi

Android自定义View基础开发之图片加载进度条

学会了Paint,Canvas的基本用法之后,我们就可以动手开始实践了,先写个简单的图片加载进度条看看. 按照惯例,先看效果图,再决定要不要往下看: 既然看到这里了,应该是想了解这个图片加载进度条了,我们先看具体用法,再看自定义View的实现: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.co

Android自定义控件制作显示进度的Button

最近看到一些应用在下载文件的时候,并没有额外弹出进度条,而是很炫的使用启动下载任务的Button直接显示文件的下载进度,通过改变其背景色,从左向右推进,直到填满整个Button时,意味着下载任务的完成. 除了这种效果,还看到某酷的视频客户端,在观看过的视频对应的按钮上,会给该按钮添加一个描边效果,4条边,每条边代表25%的进度,由上沿开始,顺时针最终到左边沿,则代表100%的进度,这种效果也很不错. 自己也研究了一下,写了个自定义的button,下面是效果, 普通的填充效果: 描边的效果: 自定

Android自定义水平进度条的圆角进度

平时项目中经常用到自定义进度条样式,我们一般实现的也是下面的第一种,至于第二种的圆角进度,网上介绍的资料也不是很多,这里一起展示一下这两种的实现. 下面开始看代码,先从主界面布局开始看起: <ProgressBar style="@android:style/Widget.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="20dp&qu

Android 带进度条的WebView 示例代码

前言 如果不使用系统自带的TitleBar(即Activity被设置@android:style/Theme.NoTitleBar),那就需要自己来写进度条了,这里封装了一个自定义控件和加载网页的公共Activity,方便使用. 正文 一.截图 二.自定义控件 复制代码 /** * 带进度条的WebView * http://www.cnblogs.com/over140/archive/2013/03/07/2947721.html * */ @SuppressWarnings("deprec

Android自定义View仿QQ等级天数进度

最近一直都在看自定义View这一块.差不多一个星期了吧.这个星期坚持每天更新博客,感觉自己的技术也有点突破,对自定义View的计算也有了更深的认识. 今天看到手机一个成长天数进度的控件,觉得挺有意思的,于是想自己也写一个.效果如下: 由图可以知道,这里面有很多个元素,首先是背景的矩形区域,其次就是两个环形,然后三个Text文本.其实不复杂,我们一点一点的去实现. 首先呢,画矩形背景.这里用到一个RectF的类,这个类包含一个矩形的四个单精度浮点坐标.矩形通过上下左右4个边的坐标来表示一个矩形.这

Android定制RadioButton样式三种实现方法

三种方法 1.使用XML文件进行定义 res/drawable/radio.xml 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 未选中-> <item android:state_checked=&qu

Android实现个性化的进度条

1.案例效果图 2.准备素材 progress1.png(78*78) progress2.png(78*78) 3.原理 采用一张图片作为ProgressBar的背景图片(一般采用颜色比较浅的).另一张是进度条的图片(一般采用颜色比较深的图片).进度在滚动时:进度图片逐步显示,背景图片逐步隐藏,达到上面的效果. 4.灵感来自Android控件提供的源码 4.1 默认带进度的进度条,如下图 <ProgressBar android:id="@+id/progressBar2" s

Android自定义View之圆形进度条式按钮

介绍 今天上班的时候有个哥们问我怎么去实现一个按钮式的进度条,先来看看他需要实现的效果图. 和普通的圆形进度条类似,只是中间的地方有两个状态表示,未开始,暂停状态.而且他说圆形进度的功能已经实现了.那么我们只需要对中间的两个状态做处理就行了. 先来看看实现的效果图: 上面说了我们只需要处理中间状态的变化就可以了,对于进度的处理直接使用了弘洋文章中实现: http://blog.csdn.net/lmj623565791/article/details/43371299 下面开始具体实现. 具体实

android自定义view制作圆形进度条效果

还是我们自定View的那几个步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 [ 3.重写onMesure ] 4.重写onDraw 1.自定义属性: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CustomTitleView"> <attr name="m

Android自定义View实现环形进度条的思路与实例

前言 前段时间看到了豆瓣FM的音乐播放界面,有一个环形的进度条,非常的好看,于是想了想,为什么不自己做一个呢,于是就开始了自定义的过程 豆瓣FM的播放界面如下图: 功能分析 虽然功能比较简单,但是仍然需要仔细分析 1.图标外还有一圈圆圈,可以设置宽度 2.圆形进度条和进度条底部,可以设置宽度,颜色等 3.内部有一个圆形图片,可旋转 实现思路分析 1.可以设置宽度的圆圈 这个比较容易,直接在onDraw方法中使用canvas绘制即可,当然,在间距和半径的处理上需要仔细,控件本体其实还是一个长方形,

Android自定义漂亮的圆形进度条

这几天对Android中实现画圆弧及圆弧效果中所实现的效果进行了修改,改为进度圆心进度条,效果如图所示 TasksCompletedView.java 代码如下 import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; impo

Android自定义View实现渐变色进度条

在网上看到一个进度条效果图,非常美观,如下: 进行效果分解: 1.渐变色,看起来颜色变化并不复杂,使用LinearGradient应该可以实现. 2.圆头,无非是画两个圆,外圆使用渐变色的颜色,内圆固定为白色. 3.灰底,还没有走到的进度部分为灰色. 4.进度值,使用文本来显示: 5.弧形的头部,考虑使用直线进行连接,或者使用曲线,例如贝塞尔曲线: 我首先初步实现了进度条的模样,发现样子有了,却不太美观. 反思了一下,我只是个写代码的,对于哪种比例比较美观,是没有清晰的认识的,所以,还是参考原图

Android自定义view实现水波进度条控件

通过自定义view实现了一个水滴滴落到水波面,溅起水花并且水波流动上涨的进度条控件.之前看到过好多水波流动的进度条,感觉欠缺些东西,就想到了水滴到水平面,溅起水花然后水流动上涨的进度条效果,于是自己动手写了出来.效果如下,视频录制有些卡顿,实际会流畅很多. 一.用法 1.布局文件中添加WaveProgressView,circleColor属性为圆环颜色,waterColor属性为水波水滴的颜色,progress属性为初始的进度 <com.yhongm.wave_progress_view.Wa

android自定义view实现数字进度条

之前看到过一个数字进度条,一直想写,今天就把这个实现下,想起来也是很简单的,先看下实现的效果: 思路: 绘制2根线 绘制进度条的文字,不断的改变起点和终点,然后没多少时间去更新UI就ok,在这就不画图了,看代码就看的明白,不要想的很复杂! package com.tuya; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import a

Android自定义View实现投票进度条

本文实例为大家分享了Android投票进度条的具体代码,供大家参考,具体内容如下 效果展示 功能属性介绍 <!-- MatchSupportProgressBar --> <declare-styleable name="MatchSupportProgressBar"> <!-- 进度条圆角角度 --> <attr name="progress_radio" format="string"><

Android自定义带水滴的进度条样式(带渐变色效果)

一.直接看效果 二.直接上代码 1.自定义控件部分 package com.susan.project.myapplication; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.grap

Android自定义view渐变圆形动画

本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 <resources> <declare-styleable name="ProgressRing"> <!--进度起始色--> <attr name="pr_progress_start_color" format="color" /> <!--