WebViewAndroid AppAndroid开发经验谈

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

2017-10-20  本文已影响58人  肖丹晨

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

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

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

相关文章
Android在H5加载完成前显示加载进度条
Android 在H5加载完成前显示加载进度条2

实现方案:

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

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

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

//自定义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是否仍在绘制,来判读是否需要取消进度条的显示。

//如果发现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我也很开心。

方案3

这两天忽然发现了别的人写的一篇文章,在这里贴一下,
原文链接
关键代码:

boolean loadingFinished = true;
boolean redirect = false;

mWebView.setWebViewClient(new WebViewClient() {

   @Override
   public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
       if (!loadingFinished) {
          redirect = true;
       }

   loadingFinished = false;
   view.loadUrl(urlNewString);
   return true;
   }

   @Override
   public void onPageStarted(WebView view, String url, Bitmap facIcon) {
        loadingFinished = false;
        //SHOW LOADING IF IT ISNT ALREADY VISIBLE  
    }

   @Override
   public void onPageFinished(WebView view, String url) {
       if(!redirect){
          loadingFinished = true;
       }

       if(loadingFinished && !redirect){
         //HIDE LOADING IT HAS FINISHED
       } else{
          redirect = false; 
       }

    }
});
上一篇下一篇

猜你喜欢

热点阅读