Android -- 真正的 高仿微信 打开网页的进度条效果
(本博客为原创,http://www.cnblogs.com/linguanh/)
目录:
一,为什么说是真正的高仿?
二,为什么要搞缓慢效果?
三,我的实现思路
四,代码,内含注释
五,使用方法与截图
六,完整项目
一,为什么说是真正的高仿?
阐述这个问题前,先说下之前网上的,各位可以复制这段字,去百度一下 "仿微信打开网页的进度条效果" ,你会看到有很多类似的文章,不过他们有个共同点,就是实现方法都是一样的,而且,都忽略了微信加载网页时,进度条的缓慢动画效果,它不是生硬地一滑而过,而是用户体验很好,有个速度的变化,由慢到快的效果,语言难于描述,相信各位都有下载微信,可以随便打开个公众号的文章看看效果。
好了,上面说到,之前网上的方法都是都忽略了微信加载网页时,进度条的缓慢动画效果,实现代码也是千篇一律,如下:
/** 先实例化个进度条 */
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;
}
}
}
六,完整项目
https://github.com/af913337456/SlowlyProgressBar
Android -- 真正的 高仿微信 打开网页的进度条效果的更多相关文章
- iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码
iOS精选源码 iOS高仿微信完整项目源码 Khala: Swift 编写的iOS/macOS 路由框架 微信左滑删除效果的实现与TableViewCell的常用样式介绍 实现阴影圆角并存,渐变色背景 ...
- Android开发之高仿微信图片选择器
记得刚开始做Andriod项目那会,经常会碰到一些上传图片的功能需求,特别是社交类的app,比如用户头像,说说配图,商品配图等功能都需要让我们到系统相册去选取图片,但官方却没有提供可以选取多张图片的相 ...
- Android高仿微信(一)——如何消除启动时的白屏
默认情况下,APP启动时会先把屏幕刷成白色,然后才绘制第一个Activity中的View,这两个步骤之间的延迟会造成启动后先看到白屏(时间大概为1秒左右).时间不长,但是我们也看到,一般的APP时不存 ...
- Android 高仿微信实时聊天 基于百度云推送
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38799363 ,本文出自:[张鸿洋的博客] 一直在仿微信界面,今天终于有幸利用百 ...
- Android ActionBar应用实战,高仿微信主界面的设计
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/26365683 经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对 ...
- Android 高仿微信头像截取 打造不一样的自定义控件
转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/39761281,本文出自:[张鸿洋的博客] 1.概述 前面已经写了关于检测手势识别 ...
- android高仿微信拍照、多选、预览、删除(去除相片)相冊功能
先声明授人与鱼不如授人与渔,仅仅能提供一个思路,当然须要源代码的同学能够私下有偿问我要源代码:QQ:508181017 工作了将近三年时间了,一直没正儿八经的研究系统自带的相冊和拍照,这回来个高仿微信 ...
- Android 高仿微信即时聊天 百度云为基础的推
转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/38799363 ,本文出自:[张鸿洋的博客] 一直在仿微信界面,今天最终有幸利用百 ...
- Android 高仿微信6.0主界面 带你玩转切换图标变色
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41087219,本文出自:[张鸿洋的博客] 1.概述 学习Android少不了模仿 ...
随机推荐
- Python 爬虫模拟登陆知乎
在之前写过一篇使用python爬虫爬取电影天堂资源的博客,重点是如何解析页面和提高爬虫的效率.由于电影天堂上的资源获取权限是所有人都一样的,所以不需要进行登录验证操作,写完那篇文章后又花了些时间研究了 ...
- Node-Webkit打包
1.node-webkit是什么? NW.js is an app runtime based on Chromium and node.js. You can write native apps i ...
- 安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路
针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest ...
- [.NET] 利用 async & await 的异步编程
利用 async & await 的异步编程 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/5922573.html 目录 异步编程的简介 异 ...
- angular2系列教程(十一)路由嵌套、路由生命周期、matrix URL notation
今天我们要讲的是ng2的路由的第二部分,包括路由嵌套.路由生命周期等知识点. 例子 例子仍然是上节课的例子:
- 极光推送和友盟推送,ios端和安卓端的后端调试设置
我是最后端的,这两天搞了一个app项目,前端安卓使用友盟很方便,调试比较顺利,然后ios就遇到各种问题了,证书.发送成功推送不成功,测试时用的TestMode(),ios上架之后就必须用product ...
- const let,console.log('a',a)跟console.log('a'+a)的区别
const 创建一个只读的常量 let块级作用域 const let重复赋值都会报错 console.log('a',a) a console.log('a'+a) a2 逗号的值会有空格:用加号的值 ...
- 【JavaScript】innerHTML、innerText和outerHTML的用法区别
用法: <div id="test"> <span style="color:red">test1</span> tes ...
- 网站里加入QQ在线客服
1.开启"QQ在线状态"服务 http://jingyan.baidu.com/article/b24f6c823425a586bfe5da1f.html http://www. ...
- 满堂红CIO邓劲翔:房屋中介突围
人脸识别.客户关系管理进度监控.业务流程实时监控.网站访问人数及流量实时监控等实际企业应用场景淋漓尽致.羽羽如生的以大屏幕上图表形式展现在人们面前,如果你不去继续询问,你不会知道这是一家才刚刚在房地产 ...