前言
我们经常打开网页,顶部大部分都会出现一个进度条来告知用户这个网页的加载过程。例如我们打开微信内的文章时会看到文章顶部有一个绿色的进度条。那我们怎么去实现该功能呢?
WebView源码
public class WebView extends AbsoluteLayout implements OnGlobalFocusChangeListener, OnHierarchyChangeListener {
public static final int RENDERER_PRIORITY_BOUND = 1;
public static final int RENDERER_PRIORITY_IMPORTANT = 2;
public static final int RENDERER_PRIORITY_WAIVED = 0;
public static final String SCHEME_GEO = "geo:0,0?q=";
public static final String SCHEME_MAILTO = "mailto:";
public static final String SCHEME_TEL = "tel:";
public WebView(Context context) {
super((Context)null, (AttributeSet)null, 0, 0);
throw new RuntimeException("Stub!");
}
//省略 ......
}
我们可以看到WebView其实是继承了AbsoluteLayout 。所有我们可以自定义一个MyWebView继承WebView即可。
自定义WebView
public class MyWebView extends WebView {
private ProgressBar mProgressBar;
public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
//初始化一个进度条控件
mProgressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
//设置params
mProgressBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 5, 0, 0));
//设置进度条颜色(可以根据自己的需求自定义)
Drawable drawable = context.getResources().getDrawable(R.drawable.progressbar_webview);
mProgressBar.setProgressDrawable(drawable);
//将ProgressBar控件添加到MyWebView上
addView(mProgressBar);
setWebChromeClient(new WebChromeClient());
setWebViewClient(new WebClient());
//设置WebSettings
setting();
}
/*****设置WebSettings ****/
private void setting() {
WebSettings settings = getSettings();
//支持javascript
settings.setJavaScriptEnabled(true);
//是否可以缩放
settings.setSupportZoom(true);
// 设置出现缩放工具
settings.setBuiltInZoomControls(false);
//扩大比例的缩放
settings.setUseWideViewPort(true);
//自适应屏幕
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
settings.setLoadWithOverviewMode(true);
//增加WebView对localStorage的支持
settings.setDomStorageEnabled(true);
settings.setAllowFileAccess(true);
//不使用缓存 LOAD_NO_CACHE 优先加载缓存LOAD_CACHE_ELSE_NETWORK
//settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
//解决图片不显示
settings.setBlockNetworkImage(false);
// 设置允许JS弹窗
settings.setJavaScriptCanOpenWindowsAutomatically(true);
}
public class WebChromeClient extends android.webkit.WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
//判断进度是否到了100,如果到了就要隐藏ProgressBar,如果没有就更新进度状态。
if (newProgress == 100) {
mProgressBar.setVisibility(GONE);
} else {
if (mProgressBar.getVisibility() == GONE) {
mProgressBar.setVisibility(VISIBLE);
}
mProgressBar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
}
public class WebClient extends android.webkit.WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//app内加载,防止跳转到外部的浏览器。
view.loadUrl(url);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
//有时候需求是要获取网页中的标题,故通过接口监听来实现。
if (titleListener != null) {
titleListener.onTitle(view.getTitle());
}
super.onPageFinished(view, url);
}
}
/**************** 网页的标题监听 ****************/
TitleListener titleListener;
public void setTitleListener(TitleListener titleListener) {
this.titleListener = titleListener;
}
public interface TitleListener{
void onTitle(String title);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
//更新ProgressBar的params
LayoutParams lp = (LayoutParams) mProgressBar.getLayoutParams();
lp.x = l;
lp.y = t;
mProgressBar.setLayoutParams(lp);
super.onScrollChanged(l, t, oldl, oldt);
}
}
里面的注释比较详细了,就不再一一的介绍了。里面用到的progressbar_webview文件也贴一下吧,在res/drawable/目录下即可,仅供参数。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="2dp" />
<gradient
android:angle="270"
android:centerColor="#E3E3E3"
android:endColor="#E6E6E6"
android:startColor="#C8C8C8" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="2dp" />
<gradient
android:centerColor="#8DC54D"
android:endColor="#8DC54D"
android:startColor="#8DC54D" />
</shape>
</clip>
</item>
</layer-list>
补充
WebView容易造成内存泄漏。用户可以参考其他的博客,本文不重点说明。
一般常用的代码,在onDestroy()方法写。
@Override
protected void onDestroy() {
if (webView != null) {
webView.stopLoading();
webView.removeAllViews();
webView.destroy();
//.....还有其他的方法,就不一一写了。
}
super.onDestroy();
}