我有一个非模态的 BottomSheet,其中有一个使用 AndroidView 的 Compose 中的 WebView。
WebView 显示 Google 地图站点,我使用参数来显示使用 FusedLocationProviderClient 等获取的位置。
我希望禁用用户与 WebView 的交互,我在here读到有两个建议:添加覆盖或覆盖触摸事件。但这是一个非常古老的线程,我不知道如何在 AndroidView 中使用 Compose 执行任何建议。
以下是我的代码:
底页:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LocationScreen(startLocationUpdates: ()->Unit, context: Context, currentLocation: LatLng) {
val permissions = arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
)
val launchMultiplePermissions = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissionMaps ->
val areGranted = permissionMaps.values.reduce { acc, next -> acc && next }
if (areGranted) {
locationRequired = true
startLocationUpdates()
Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show()
}
}
var readable by remember { mutableStateOf("") }
//val scope = rememberCoroutineScope()
//I HAVE THIS COMMENTED BECAUSE THE BUTTON THAT IS USUALLY LOCATED IN THE BOTTOMSHEET TO CLOSE IT IS COVER BY THE WEBVIEW AND CAN'T BE USED
val scaffoldState = rememberBottomSheetScaffoldState()
BottomSheetScaffold(
scaffoldState = scaffoldState,
sheetPeekHeight = 590.dp, //The Bottom Sheet will show the WebView partially but all that is needed
sheetSwipeEnabled = false, //For the moment I don't want the Bottom Sheet to occupy the full screen
sheetContent = {
Column(
Modifier
.fillMaxWidth()
.padding(6.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
if (currentLocation.latitude != 0.toDouble() && currentLocation.longitude != 0.toDouble() && readable != "") {
WebViewScreen(location = currentLocation) //HERE IS THE CALL TO THE ANDROIDVIEW/WEBVIEW
} else {Text(text = "Please click [Get your location]")}
}
}) { innerPadding ->
Box(Modifier.padding(innerPadding)) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Your location: ${currentLocation.latitude}/${currentLocation.longitude}")
if (currentLocation.latitude != 0.toDouble() && currentLocation.longitude != 0.toDouble()) {
Text(
text = "Readable location: $currentLocation"
)
location = ""
readable = getReadableLocation(currentLocation.latitude, currentLocation.longitude, context) //HERE I USE A GEOCODER TO GET THE ADDRESS
glocation = currentLocation
}
Button(onClick = {
if (permissions.all {
ContextCompat.checkSelfPermission(
context,
it
) == PackageManager.PERMISSION_GRANTED
}) {
//Get Locations
startLocationUpdates() //THIS IS WHERE I GET THE LOCATION/COORDINATES
} else {
launchMultiplePermissions.launch(permissions)
}
//run = true
}) {
Text(text = "Get your location")
}
}
}
}
}
AndroidView 与 WebView:
@Composable
fun WebViewScreen(location: LatLng){
//val urladdress = URLDecoder.decode(address,"utf-8")
val url = "http://maps.google.com/maps?z=16&t=h&q=loc:${location.latitude}+${location.longitude}&hl=${Locale.getDefault().language}"
AndroidView(
factory = { context ->
WebView(context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
settings.javaScriptEnabled = true
webViewClient = WebViewClient()
settings.loadWithOverviewMode = true
settings.useWideViewPort = true
settings.setSupportZoom(true)
loadUrl(url)
}
},
update = { webView ->
webView.loadUrl(url)
}
)
}
我没有提供位置代码或地址代码,因为本问题不需要此代码。
找到了一种禁用用户与 WebView 交互的替代方法。
我没有添加覆盖,而是采用触摸事件方法。
以下是代码:
AndroidView(
modifier = Modifier
//.focusProperties { canFocus = false }
.pointerInteropFilter {
when (it.action) {
MotionEvent.ACTION_DOWN -> {}
MotionEvent.ACTION_MOVE -> {}
MotionEvent.ACTION_UP -> {}
else -> false
}
true
},
factory = { context ->
WebView(context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
settings.javaScriptEnabled = true
webViewClient = WebViewClient()
settings.loadWithOverviewMode = true
settings.useWideViewPort = true
settings.setSupportZoom(true)
loadUrl(url)
}
},
update = { webView ->
webView.loadUrl(url)
}
)
“pointerInteropFilter”捕获父 AndroidView 中的所有移动,阻止子 WebView 中的所有交互。 例如,如果您想在特定区域允许触摸事件,您可以检测 AndroidView 内的坐标,并允许与您需要响应事件的子项上方的区域相对应的坐标。