WebView是我们在开发中经常会使用到的组件,我们可以用它来展示动态的Html页面。在Android的View体系中,我们可以直接在xml中添加WebView组件即可使用。但是在Jetpack Compose中,并没有可以直接使用的WebView组件。那么我们该如何在Compose中使用WebView呢?
这篇文章将介绍如何在Jetpack Compose中使用WebView,并使用其基础功能。
添加权限
首先,我们需要在Android Manifest中添加权限:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:usesCleartextTraffic="true">
</application>
</manifest>
AndroidView
然后我们就需要创建一个Composable组件来展示Web页面:
@Composable
fun WebView(){
// Declare a string that contains a url
val mUrl = "https://www.google.com"
// Adding a WebView inside AndroidView
// with layout as full screen
AndroidView(factory = {
WebView(it).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
}, update = {
it.loadUrl(mUrl)
})
}
可以看到,我们使用了AndroidView来包裹WebView组件。在它factory方法中,我们创建一个AndroidX WebView作为实际的展示组件并为其设置layoutParams。最后,我们在它的update方法中调用了loadUrl方法来加载链接。
WebViewClient
如果我们需要拦截特定的URL该怎么实现呢?这里和View一样,我们只需要自定义一个WebViewClient,并重写shouldOverrideUrlLoading即可:
@Composable
fun WebView(){
// Declare a string that contains a url
val mUrl = "https://www.google.com"
// Adding a WebView inside AndroidView
// with layout as full screen
AndroidView(factory = {
WebView(it).apply {
this.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
this.webViewClient = CustomWebViewClient()
}
}, update = {
it.loadUrl(mUrl)
})
}
class CustomWebViewClient: WebViewClient(){
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if(url != null && url.startsWith("https://google.com")){
return true
}
return false
}
}
WebChromeClient
同样的,我们也可以通过自定义一个WebChromeClient来监听一些Web事件:
@Composable
fun WebView(){
// Declare a string that contains a url
val mUrl = "https://www.google.com"
// Adding a WebView inside AndroidView
// with layout as full screen
AndroidView(factory = {
WebView(it).apply {
this.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
this.webChromeClient = CustomWebChromeClient()
}
}, update = {
it.loadUrl(mUrl)
})
}
class CustomWebChromeClient : WebChromeClient() {
override fun onCloseWindow(window: WebView?) {}
override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {}
}
Library
但是这只适用于无状态的单次加载,如果我们需要获取网页的标题,加载状态,当前加载Url该怎么办呢?同样的,如果我们需要控制网页的前进,后退,以及加载新链接呢?更复杂的是如果我们需要在加载Url的基础上同时支持Post和Html代码的加载呢?
幸运的是,现在已经有一个成熟的第三方库可以提供这些能力的支持。它提供了一个可以直接在Compose中使用的WebView组件。这样,开发者就不需要自行去实现WebView的封装逻辑。此外,它还支持Web页面属性的获取,加载状态的监听等能力,开箱即用,非常方便。
https://github.com/KevinnZou/compose-webview
它的基础使用非常简单,如下就可以完成一个Url的加载和展示:
val state = rememberWebViewState("https://example.com")
WebView(
state
)
对于它的具体使用介绍,大家可以参考这篇文章:
https://blog.csdn.net/weixin_51235693/article/details/135958631