WebView 不在 Compose 内滚动。 我需要使用 Compose 将 WebView 放入 BottomSheet 中。即使我们使用例如 WebView 也不会滚动的问题NestedWebView,或NestedScrollWebView。 如果我将 WebView 放入 NestedScrollView 中,它仍然不会对滚动做出反应。
BottomSheetScaffold(
sheetContent = {
AndroidView(factory = {
NestedWebView(it).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
settings.domStorageEnabled = true
settings.javaScriptEnabled = true
settings.useWideViewPort = true
webViewClient = WebViewClient()
//loadUrl("https://contest.rippl.club/")
loadUrl("https://codeflarelimited.com")
}
})
}) {
}
解决方法之一是使用verticalScroll并将webview高度设置为WRAP_CONTENT:
val scrollState = rememberScrollState()
AndroidView(modifier = Modifier.verticalScroll(scrollState), factory = {
WebView(it).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
---//---
但是有很多网站不能使用wrap_content,例如因为像这个网站这样的内部滚动https://contest.rippl.club/。该网站不适用于该解决方法。如果我们将webview高度设置为屏幕高度,它仍然不起作用,因为verticalScroll就像ScrollView一样,所以它只会滚动到这个高度。
我还检查了这个文档https://developer.android.com/jetpack/compose/gestures#parent-compose-child-view,但对于 webview 情况没有任何作用。
这是一个小示例代码,它至少使 WebView 可以滚动:
private class MyWebView(context: Context) : WebView(context) {
val verticalScrollRange: Int get() = computeVerticalScrollRange() - height
}
@Composable
fun WebViewCompose(url: String, modifier: Modifier = Modifier, onCreated: (WebView) -> Unit = {}) {
val context = LocalContext.current
val webView: MyWebView = remember(context) {
MyWebView(context).also(onCreated)
}
DisposableEffect(webView) {
onDispose {
webView.stopLoading()
webView.destroy()
}
}
val scrollabeState = rememberScrollableState { delta ->
val scrollY = webView.scrollY
val consume = (scrollY - delta).coerceIn(0f, webView.verticalScrollRange.toFloat())
webView.scrollTo(0, consume.roundToInt())
(scrollY - webView.scrollY).toFloat()
}
AndroidView(
factory = { webView },
modifier = modifier
.scrollable(scrollabeState, Orientation.Vertical)
) { webView2 ->
webView2.loadUrl(url)
}
}
这个答案有帮助:https://stackoverflow.com/a/70195667/4256193
它对我有用:
Surface(
modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection())
) {
WebView(
state = state,
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
onCreated = { }
)
}
有一种简单的方法可以解决这个问题。我有一个和你一模一样的案例。 您需要做的就是像这样实现
pointerInput
:
AndroidView(
modifier = Modifier
.fillMaxHeight(0.9f)
.pointerInput(Unit) {
detectVerticalDragGestures { _, dragAmount ->
val initialDrag = currentVerticalDrag.value + dragAmount
val calculatedDrag = when {
initialDrag > 0 -> {
0
}
abs(initialDrag) > measuredHeight.value -> {
measuredHeight.value
}
else -> {
initialDrag.roundToInt()
}
}
currentVerticalDrag.value = calculatedDrag
}
},
factory = {
WebView(it).apply {
settings.javaScriptEnabled = true
addJavascriptInterface(jsInterface, "HTMLOUT")
webViewClient = FaqWebViewClient(
onPageLoadingStart = {
isPageLoading.value = true
},
onPageLoadComplete = {
isPageLoading.value = false
}
)
loadUrl(url)
}
}, update = { webView ->
webView.scrollTo(0, abs(currentVerticalDrag.value))
}
)
我正在使用脚手架,在内容中添加一个带有verticalScroll(rememberScrollState())的列。我测试了几个网站并且在我的案例中有效。
Scaffold(
topBar = {
// Your Top bar with e.g url, navigation etc
},
content = { pv ->
Column(
modifier = Modifier
.padding(pv)
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
AndroidView(factory = {
WebView(it).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
webViewClient = WebViewClient()
settings.javaScriptEnabled = true
settings.safeBrowsingEnabled = true
loadUrl(url)
}
}, update = {
it.loadUrl(url)
})
}
}
)