android webview 梳理

2018-12-29  本文已影响51人  前行的乌龟

webview 零零散散的点也是有一些的,今天整理一下,首先我们一般不直接使用 webview 本身,而是对给 webview 添加一个 父容器, 在里面添加进度条,错误页面等一些常用功能

这里我贴一下我使用的 webview 包装类 MyWebView ,继承自 ConstraintLayout ,实现 processbar 进度条显示,错误页面没做,大家有需求,自己去做即可

webview 的基础知识点大家看这里吧,写的很好很全

本文项目地址:BW_Libs


1. webview 常用包装类 MyWebView

MyWebView 比较简单我直接贴代码了,里面的涉及 webview 的常用设置,processbar 显示,隐藏,更新进度,重定向监听

MyWebView 布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/view_full"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <WebView
        android:id="@+id/view_webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ProgressBar
        android:id="@+id/view_progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:progressDrawable="@drawable/layer_mywebview_processbar"
        android:visibility="gone"/>

</android.support.constraint.ConstraintLayout>

MyWebView 代码

class MyWebView : ConstraintLayout {

    var mCallBack: MyWebViewCallBack? = null
    var mUrl: String = ""

    @JvmOverloads
    constructor(context: Context, attributeSet: AttributeSet? = null, defAttrStyle: Int = 0)
            : super(context, attributeSet, defAttrStyle) {

        initView()
        initWebViewSetting()
        initWebViewListener()
    }

    /**
     * 添加默认 layout 进来
     */
    private fun initView() {
        LayoutInflater.from(context).inflate(R.layout.layout_mywebview, this, true)
    }

    /**
     * 设置 webview 的各种设置
     */
    private fun initWebViewSetting() {

        var settings: WebSettings = view_webView.settings

        /**
         * js 交互设置
         */
        settings.javaScriptEnabled = true // 默认false,设置true后我们才能在WebView里与我们的JS代码进行交互
        settings.javaScriptCanOpenWindowsAutomatically = true // 设置JS是否可以打开WebView新窗口

        /**
         * 手势缩放设置
         */
        settings.setSupportZoom(true) // 支持缩放
        settings.builtInZoomControls = true // 支持手势缩放
        settings.displayZoomControls = false // 不显示缩放按钮

        /**
         * 缓存,数据库设置
         */
        settings.databaseEnabled = true//数据库存储API是否可用,默认值false。
        settings.saveFormData = true//WebView是否保存表单数据,默认值true。
        settings.domStorageEnabled = true//DOM存储API是否可用,默认false。
        settings.setGeolocationEnabled(true)//定位是否可用,默认为true。
        settings.setAppCacheEnabled(true)//应用缓存API是否可用,默认值false, 结合setAppCachePath(String)使用。

        /**
         * 自适应设置
         */
        settings.useWideViewPort = true // 将图片调整到适合WebView的大小
        settings.loadWithOverviewMode = true // 自适应屏幕

        /**
         * 滚动样式设置
         */
        view_webView.isHorizontalScrollBarEnabled = false//去掉webview的滚动条,水平不显示
        view_webView.isScrollbarFadingEnabled = true
        view_webView.scrollBarStyle = View.SCROLLBARS_OUTSIDE_OVERLAY
        view_webView.overScrollMode = View.OVER_SCROLL_NEVER // 取消WebView中滚动或拖动到顶部、底部时的阴影
    }

    /**
     * 设置 webview  监听
     */
    private fun initWebViewListener() {

        view_webView.webViewClient = object : WebViewClient() {

            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)

                view_progressBar.visibility = View.VISIBLE
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)

                view_progressBar.visibility = View.GONE
            }

            override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                var result = false

                if (mCallBack != null) {
                    result = mCallBack?.shouldOverrideUrlLoading(view, url)!!
                    return result
                }
                view_webView.loadUrl(url)
                return result
            }
        }

        view_webView.webChromeClient = object : WebChromeClient() {

            // 更新进度
            override fun onProgressChanged(view: WebView?, progress: Int) {
                super.onProgressChanged(view, progress)

                if (progress >= 100) {
                    view_progressBar.visibility = View.GONE
                    return
                }

                if (view_progressBar.visibility == View.GONE) {
                    view_progressBar.visibility = View.VISIBLE
                }

                view_progressBar.progress = progress
            }
        }

    }

    fun loadUrl(url: String) {
        this.mUrl = url
        view_webView.loadUrl(url)
    }

    fun onDestroy() {
        view_webView.setVisibility(View.GONE)
        view_webView.destroy()
    }

    fun goBack(): Boolean {
        if (view_webView.canGoBack()) {
            view_webView.goBack()
            return true
        }
        return false
    }

    interface MyWebViewCallBack {

        fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean
    }

}

直接使用就行,像 webview 一样用

class WebViewActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_web_view)

        view_myWebView.loadUrl("http://www.sina.com")
    }
}

webview 几个注意点

  1. 可以加载 assets 里面的 html 页面
//例如:加载assets文件夹下的test.html页面
mWebView.loadUrl("file:///android_asset/test.html")
//例如:加载网页
mWebView.loadUrl("http://www.baidu.com")
  1. webview 重定向问题

如果只是这样调用mWebView.loadUrl()加载的话,那么当你点击页面中的链接时,页面将会在你手机默认的浏览器上打开。那如果想要页面在App内中打开的话,那么就得设置setWebViewClient

mWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
                mWebView.loadUrl(url);
                return true;
            }
        }
    });

webview 和 html 页面 js 交互

与 js 交互,包括 android 调 js 方法,js 调 android 方法

  1. 启动 js 调用可能
    WebSettings webSettings = mWebView.getSettings();
    //设置为可调用js方法
    webSettings.setJavaScriptEnabled(true);
  1. android 调 js 方法,下面是有返回值的,
mWebView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            Log.e(TAG, "onReceiveValue value=" + value);
        }
    });

没返回值的也可以这么写

mWebView.loadUrl("javascript:do()")

js 范本如下

<script type="text/javascript">
    function sum(a,b){
    return a+b;
    }
    function do(){
    document.getElementById("p").innerHTML="hello world";
    }
</script>
  1. js 调 android 方法

在Android4.2以上可以直接使用@JavascriptInterface注解来声明

 public class JsInteration {
    @JavascriptInterface
    public String back() {
        return "hello world";
    }
}

定义完这个方法后再调用

 mWebView.addJavascriptInterface(new JsInteration(), "android");

js 范本

<script type="text/javascript">
     function s(){
     //调用Java的back()方法
    var result =window.android.back();
    document.getElementById("p").innerHTML=result;
    }
   
</script>

webview 其他

JSBridge 这是一个开源的和 js 交互的库,据说比官方实现兼容性好,这个没试过

wenview 若是涉及到视频播放需要全屏,请看这个

关于外链启动本 app ,包括外部 的 html ,这个我在下面这篇文章的后部记录了一些

webview 这块也有开源框架,比如腾信 X5,UC的,不过 UC 的要收费

腾信 X5 看下面这篇吧

上一篇 下一篇

猜你喜欢

热点阅读