Skip to content

Instantly share code, notes, and snippets.

@TheMelody
Last active March 28, 2024 06:43
Show Gist options
  • Save TheMelody/6ec3fcba6d57f544465651acc480ff39 to your computer and use it in GitHub Desktop.
Save TheMelody/6ec3fcba6d57f544465651acc480ff39 to your computer and use it in GitHub Desktop.
Jetpack Compose - WebView 使用方法
@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)
}
}
}
var rememberWebViewProgress: Int by remember { mutableStateOf(-1) }
Box {
CustomWebView(
modifier = Modifier.fillMaxSize(),
url = "https://www.baidu.com/",
onProgressChange = { progress ->
rememberWebViewProgress = progress
},
initSettings = { settings ->
settings?.apply {
//支持js交互
javaScriptEnabled = true
//将图片调整到适合webView的大小
useWideViewPort = true
//缩放至屏幕的大小
loadWithOverviewMode = true
//缩放操作
setSupportZoom(true)
builtInZoomControls = true
displayZoomControls = true
//是否支持通过JS打开新窗口
javaScriptCanOpenWindowsAutomatically = true
//不加载缓存内容
cacheMode = WebSettings.LOAD_NO_CACHE
}
}, onBack = { webView ->
if (webView?.canGoBack() == true) {
webView.goBack()
} else {
finish()
}
}, onReceivedError = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//Log.d("AAAA", ">>>>>>${it?.description}")
}
}
)
LinearProgressIndicator(
progress = rememberWebViewProgress * 1.0F / 100F,
modifier = Modifier
.fillMaxWidth()
.height(if (rememberWebViewProgress == 100) 0.dp else 5.dp),
color = Color.Red
)
}
@zhongmengfeng
Copy link

你好 我再使用当前案例去加载本地vue项目,由于我刚接触compose,当前无法加载出来,是什么原因呢?

@TheMelody
Copy link
Author

你好 我再使用当前案例去加载本地vue项目,由于我刚接触compose,当前无法加载出来,是什么原因呢?

vue是不是用了window.android呢?如果是的话,建议在onPageFinished通过evaluateJavascript通知vue再去调用window.android相关代码试试呢。其他问题,可以重写onReceivedError看看报了什么错误

@zhongmengfeng
Copy link

hi,使用
image
gai该片段代码,任然无法成功预览,那么我想曲线救国,再compose中我是否能通过home.java 文件去跳转mainactivity.kt
文件呢 ?compose是单页结构 我这样的操作是否会成功?

@TheMelody
Copy link
Author

hi,使用 image gai该片段代码,任然无法成功预览,那么我想曲线救国,再compose中我是否能通过home.java 文件去跳转mainactivity.kt 文件呢 ?compose是单页结构 我这样的操作是否会成功?

方法正确执行了吗?没有日志输出吗?onReceivedError也没有吗?是http的url?

@zhongmengfeng
Copy link

页面加载出来 但是样式没有加载成功,使用的是http的url,onReceivedError返回的是null

@TheMelody
Copy link
Author

页面加载出来 但是样式没有加载成功,使用的是http的url,onReceivedError返回的是null

你看看是不是vue哪里不对,baidu是可以加载出来的吧

@zhongmengfeng
Copy link

感谢您的帮助,排查出问题原因,已解决,抱歉浪费了您的时间

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment