盒子
盒子
文章目录
  1. 实现方案:
    1. 方案1:监测WebView的绘制高度
    2. 方案2:监测WebView的绘制是否停止

Android 在H5加载完成前显示加载进度条2

前言
在之前的文章中,我曾经给出了一种控制进度条显示和消失时机的方式。经过实际的测试发现,很多情况下然并卵。于是乎又有了本篇,虽然还不够完美,但是写出来给大家提供个思路。
《Android在H5加载完成前显示加载进度条》

欢迎加入学习小组QQ群: 193765960

版权归作者所有,如有转发,请注明文章出处:https://xiaodanchen.github.io/archives/

实现方案:

其实在采用最终方案前,作者还使用了另一种方案,本来不想写出来,但是现在想想,那也是一种可以优化的方向,所以还是说一说吧,暂且称为方案1。

方案1:监测WebView的绘制高度

监听WebView的绘制高度,设定一个阈值,当达到阈值后取消加载进度条的显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//自定义WebView,重写OnDraw方法:示例代码
public class WebpView extends WebView {
//自定义接口,用来回调控制进度条的显示和取消
public static interface ProgressListener{
void onShowLoading();
void onCancelLoading();
}
private ProgressListener mLinstner;
public void setProgressListener(ProgressListener listener){
mLinstner = listener;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//获取当前绘制的高度
curHelght = canvas.getHeight();
//如果当前绘制的高度超过屏幕高度的70%,则取消进度条显示
if(curHelght>screenHeight*0.7){
if(null != mLinstner){
mLinstner.onCancelLoading();
}
}
}
}

方案1存在一个问题:
如果我们需要加载的H5完整的高度本来就小于我们设定的阈值,进度条取消的回调不会被触发的。
所以我进一步思考,灵光乍现,有了方案2。
方案1有个可以探索的方向:如果可以有办法获取H5 UI的高度,则可以根据H5的高度为基准来控制显示,但是可能H5的高度很难后者没有方法获取,所以这种思路不太具有普适价值。

方案2:监测WebView的绘制是否停止

以一定的时间跨度去检测WebView是否仍在绘制,来判读是否需要取消进度条的显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//如果发现500毫秒内,WebView没有绘制,则取消进度条显示
public class WebpView extends WebView {
public WebpView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public WebpView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WebpView(Context context) {
super(context);
}
private OnLoadFinishListener mOnLoadFinishListener;
private Handler mHandler;
private long lasttime;
private Runnable mdelay = new Runnable(){
public void run() {
if(System.currentTimeMillis() - lasttime >500){
if(mOnLoadFinishListener!= null){
mOnLoadFinishListener.onLoadFinish();
}
}
}
};
public interface OnLoadFinishListener{
public void onLoadFinish();
}
public void setOnLoadFinishListener(OnLoadFinishListener onLoadFinishListener){
this.mOnLoadFinishListener = onLoadFinishListener;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
lasttime = System.currentTimeMillis();
if(null == mHandler){
mHandler = new Handler();
}
mHandler.postDelayed(mdelay, 550);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mHandler = getHandler();
if(mHandler == null){
mHandler = new Handler();
}
}
@Override
protected void onDetachedFromWindow() {
if(mHandler != null){
mHandler.removeCallbacksAndMessages(null);
mHandler = null;
mdelay = null;
}
if(mOnLoadFinishListener!= null){
mOnLoadFinishListener.onLoadFinish();
mOnLoadFinishListener = null;
}
super.onDetachedFromWindow();
}
}

方案2也并不完美,比如当网络不好的时候,延时超过500毫秒的时候,我们的加载进度条仍然会消失。但是相比其他方案,已经精准多了。
若果想要解决网络延时下的加载显示问题,可能还得进一步优化,这个如果我以后做了这方面的工作,会再写文章做进一步的补充。

看到这篇文章的小伙伴们,如果你们有更加好的方案,请在尽情鄙视作者的同时记得加QQ群分享一下方案啊,这样你喊我LOW B我也很开心。

扫描加群
好好学习,天天向上!