Android 顶部带进度条的WebView

来源:互联网 发布:淘宝怎么挣钱 编辑:程序博客网 时间:2024/05/20 04:09

描述

现在h5越来越火,很多app中都会有用到h5,比如新闻类的app,这时就需要用到WebView控件,看微信订阅号打开详情时,都会在顶部有一个进度条,觉得比较好,在项目中用到WebView的时候也把进度条放在顶部。

实现

WebView的使用很简单, 基本上写好一次, 其他的地方只需要换一个请求地址就行了。 本例中的带顶部精度条的WebView其实也很简单, 就是在加载开始的时候把顶部的ProgressBar显示出来, 加载完成就讲WebView隐藏起来。

1. 实现原理

WebViewClient对象的方法用于控制精度条的显示和隐藏:

 // 页面开始加载@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {    mProgressBar.setVisibility(View.VISIBLE);    super.onPageStarted(view, url, favicon);}// 页面加载完成@Overridepublic void onPageFinished(WebView view, String url) {    mProgressBar.setVisibility(View.GONE);    super.onPageFinished(view, url);}

WebChromeClient对象的方法用于控制进度:

// 设置网页加载的进度条@Overridepublic void onProgressChanged(WebView view, int newProgress) {    mProgressBar.setProgress(newProgress);    super.onProgressChanged(view, newProgress);}

2. 完整代码

其实就是一个简单的组合控件,比较简单,整个实现代码如下:

public class ProgressWebView extends LinearLayout {    @Bind(R.id.web_view)    WebView mWebView;    @Bind(R.id.progress_bar)    ProgressBar mProgressBar;    private String url;    // 加载失败时显示    private String errorHtml = "<html><body><h3><br><br><br><br><br> <div align='center'> page not found !</div><h3></body></html>";    public ProgressWebView(Context context) {        this(context, null);    }    public ProgressWebView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public ProgressWebView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initView(context);    }    private void initView(Context context) {        View.inflate(context, R.layout.view_web_progress, this);        ButterKnife.bind(this);    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }    public void loadUrl(String url) {        if(url == null) {            // 显示csdn,说明url为空            url = "http://www.csdn.net/";         }         initWebview(url);    }    private void initWebview(String url) {        WebSettings webSettings = mWebView.getSettings();        webSettings.setJavaScriptEnabled(true);        // 设置可以访问文件        webSettings.setAllowFileAccess(true);        // 设置可以支持缩放        webSettings.setSupportZoom(true);        // 设置默认缩放方式尺寸是far        webSettings.setDefaultZoom(WebSettings.ZoomDensity.MEDIUM);        // 设置出现缩放工具        webSettings.setBuiltInZoomControls(false);        webSettings.setDefaultFontSize(20);        mWebView.loadUrl(url);        // 设置WebViewClient        mWebView.setWebViewClient(new WebViewClient() {            // url拦截            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                // 使用自己的WebView组件来响应Url加载事件,而不是使用默认浏览器器加载页面                view.loadUrl(url);                // 相应完成返回true                return true;                // return super.shouldOverrideUrlLoading(view, url);            }            // 页面开始加载            @Override            public void onPageStarted(WebView view, String url, Bitmap favicon) {                // 显示进度                mProgressBar.setVisibility(View.VISIBLE);                super.onPageStarted(view, url, favicon);            }            // 页面加载完成            @Override            public void onPageFinished(WebView view, String url) {                // 隐藏进度                mProgressBar.setVisibility(View.GONE);                super.onPageFinished(view, url);            }            // WebView加载的所有资源url            @Override            public void onLoadResource(WebView view, String url) {                super.onLoadResource(view, url);            }            @Override            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {                // 加载失败显示errorHtml, 写的比较简陋                view.loadData(errorHtml, "text/html", "UTF-8");                super.onReceivedError(view, errorCode, description, failingUrl);            }        });        // 设置WebChromeClient        mWebView.setWebChromeClient(new WebChromeClient() {            @Override            // 处理javascript中的alert            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {                return super.onJsAlert(view, url, message, result);            };            @Override            // 处理javascript中的confirm            public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {                return super.onJsConfirm(view, url, message, result);            };            @Override            // 处理javascript中的prompt            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {                return super.onJsPrompt(view, url, message, defaultValue, result);            };            // 设置网页加载的进度条            @Override            public void onProgressChanged(WebView view, int newProgress) {                // 加载进度                mProgressBar.setProgress(newProgress);                super.onProgressChanged(view, newProgress);            }            // 设置程序的Title            @Override            public void onReceivedTitle(WebView view, String title) {                super.onReceivedTitle(view, title);            }        });        mWebView.setOnKeyListener(new OnKeyListener() {            @Override            public boolean onKey(View v, int keyCode, KeyEvent event) {                if (event.getAction() == KeyEvent.ACTION_DOWN) {                    if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) { // 表示按返回键                        mWebView.goBack(); // 后退                        // 前进                        // webview.goForward();                        return true; // 已处理                    }                }                return false;            }        });    }    public boolean canBack() {        if (mWebView.canGoBack()) {            mWebView.goBack();            return false;        }        return true;    }}

注释写的比较清楚,也比较好懂,布局文件的实现如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <ProgressBar        android:id="@+id/progress_bar"        style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:progressDrawable="@drawable/drawable_webview_progress"        android:max="100"        android:progress="20"        android:visibility="gone" />    <WebView        android:id="@+id/web_view"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>

style只是用来限定进度条的高度,可以自己调整,定义在values/styles.xml:

    <style name="Widget.MaterialProgressBar.ProgressBar.Horizontal" parent="android:Widget.ProgressBar.Horizontal">        <item name="android:indeterminateDrawable">@null</item>        <item name="android:minHeight">4dp</item>        <item name="android:maxHeight">4dp</item>    </style>

progressDrawable是利用layer-list和shape定义的,就是指定了背景色和进度的颜色,这里可以自行调整,放在drawable/drawable_webview_progress.xml:

<?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>            <gradient                android:endColor="#ffffff"                android:startColor="#ffffff" />        </shape>    </item>    <item android:id="@android:id/progress">        <clip>            <shape>                <gradient                    android:endColor="#ff0000"                    android:startColor="#ff0000" />            </shape>        </clip>    </item></layer-list>

3. 用法

直接创建ProgressWebView对象或者写在布局文件中, 使用对象调用loadUrl, 传入地址即可:

ProgressWebView mWebView = new ProgressWebView(this);mWebView.loadUrl("https://www.baidu.com/");

4. 效果

5. 源码

点击查看源码

1 0
原创粉丝点击