🤔没有太多重要的知识点,主要是提供给大家在Compose中webView如何使用,主要是给一些『🙈不会用的童鞋』看的
1.初始化android.webkit下面的WebViewClient,WebChromeClient
val webViewChromeClient = object:WebChromeClient(){
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
}
}
val webViewClient = object: WebViewClient(){
//复写一些方法
......
}
2.AndroidView内的factory返回WebView
AndroidView(modifier = modifier,factory = { ctx ->
WebView(ctx).apply {
this.webViewClient = webViewClient
this.webChromeClient = webViewChromeClient
loadUrl(url)
//省略其他设置.....
}
})
3.创建一个CustomWebView的Compose方法
@Composable
fun CustomWebView(modifier: Modifier = Modifier,
//网络请求地址
url:String,
//自己处理返回事件
onBack: (webView:WebView?) -> Unit,
//自己选择是否接收,网页地址加载进度回调
onProgressChange: (progress:Int)->Unit = {},
//自己选择是否设置自己的WebSettings配置
initSettings: (webSettings:WebSettings?) -> Unit = {},
//自己选择是否处理onReceivedError回调事件
onReceivedError: (error: WebResourceError?) -> Unit = {})
4.CustomWebView内部实现:
- WebChromeClient()复写:onProgressChanged(),回调onProgressChange(50)
- WebViewClient()复写shouldOverrideUrlLoading(),onReceivedError()等
- 创建一个BackHandler,用于回调onBack(webView)
👇👇最终CustomWebView的实现代码如下👇👇:
@Composable
fun CustomWebView(modifier: Modifier = Modifier,
url:String,
onBack: (webView:WebView?) -> Unit,
onProgressChange: (progress:Int)->Unit = {},
initSettings: (webSettings:WebSettings?) -> Unit = {},
onReceivedError: (error: WebResourceError?) -> Unit = {}){
val webViewChromeClient = object:WebChromeClient(){
override fun onProgressChanged(view: WebView?, newProgress: Int) {
//回调网页内容加载进度
onProgressChange(newProgress)
super.onProgressChanged(view, newProgress)
}
}
val webViewClient = object: WebViewClient(){
override fun onPageStarted(view: WebView?, url: String?,
favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
onProgressChange(-1)
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
onProgressChange(100)
}
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
if(null == request?.url) return false
val showOverrideUrl = request.url.toString()
try {
if (!showOverrideUrl.startsWith("http://")
&& !showOverrideUrl.startsWith("https://")) {
//处理非http和https开头的链接地址
Intent(Intent.ACTION_VIEW, Uri.parse(showOverrideUrl)).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
view?.context?.applicationContext?.startActivity(this)
}
return true
}
}catch (e:Exception){
//没有安装和找到能打开(「xxxx://openlink.cc....」、「weixin://xxxxx」等)协议的应用
return true
}
return super.shouldOverrideUrlLoading(view, request)
}
override fun onReceivedError(
view: WebView?,
request: WebResourceRequest?,
error: WebResourceError?
) {
super.onReceivedError(view, request, error)
//自行处理....
onReceivedError(error)
}
}
var webView:WebView? = null
val coroutineScope = rememberCoroutineScope()
AndroidView(modifier = modifier,factory = { ctx ->
WebView(ctx).apply {
this.webViewClient = webViewClient
this.webChromeClient = webViewChromeClient
//回调webSettings供调用方设置webSettings的相关配置
initSettings(this.settings)
webView = this
loadUrl(url)
}
})
BackHandler {
coroutineScope.launch {
//自行控制点击了返回按键之后,关闭页面还是返回上一级网页
onBack(webView)
}
}
}
5.CustomWebView调用方法如下:
onProgressChange: (progress:Int)、 initSettings: (webSettings:WebSettings?)、 onReceivedError: (error: WebResourceError?) 这三个回调都是可选的,按需使用
var rememberWebProgress: Int by remember { mutableStateOf(-1)}
//用Box包裹一下CustomWebView和LinearProgressIndicator
//这样打开网页顶部就可以显示加载的进度了
CustomWebView(modifier = Modifier.fillMaxSize(),
url = "https://www.baidu.com/",
onProgressChange = {progress ->
rememberWebProgress = progress
},
initSettings = {settings->
settings?.apply {
//支持js交互
javaScriptEnabled = true
//....
}
}, onBack = { webView ->
//可根据需求处理此处
if (webView?.canGoBack() == true) {
//返回上一级页面
webView.goBack()
} else {
//关闭activity
finish()
}
},onReceivedError = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.d(TAG,">>>>>>${it?.description}")
}
})
LinearProgressIndicator(
progress = rememberWebProgress * 1.0F / 100F,
color = Color.Red,
modifier = Modifier
.fillMaxWidth()
.height(if (rememberWebProgress == 100) 0.dp else 5.dp))