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 几个注意点
- 可以加载 assets 里面的 html 页面
//例如:加载assets文件夹下的test.html页面
mWebView.loadUrl("file:///android_asset/test.html")
//例如:加载网页
mWebView.loadUrl("http://www.baidu.com")
- 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 方法
- 启动 js 调用可能
WebSettings webSettings = mWebView.getSettings();
//设置为可调用js方法
webSettings.setJavaScriptEnabled(true);
- 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>
- 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 看下面这篇吧
网友评论