一,为什么说是真正的高仿?
阐述这个问题前,先说下之前网上的,各位可以复制这段字,去百度一下 "仿微信打开网页的进度条效果",你会看到有很多类似的文章,不过他们有个共同点,就是实现方法都是一样的,而且,都忽略了微信加载网页时,进度条的缓慢动画效果,它不是生硬地一滑而过,而是用户体验很好,有个速度的变化,由慢到快的效果,语言难于描述,相信各位都有下载微信,可以随便打开个公众号的文章看看效果。
好了,上面说到,之前网上的方法都是都忽略了微信加载网页时,进度条的缓慢动画效果,实现代码也是千篇一律,如下:
/** 先实例化个进度条 */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,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开发之模仿微信打开网页的进度条效果(高仿),如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
总结以上是内存溢出为你收集整理的Android开发之模仿微信打开网页的进度条效果(高仿)全部内容,希望文章能够帮你解决Android开发之模仿微信打开网页的进度条效果(高仿)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)