Android WebView 在 Compose 中具有透明覆盖

问题描述 投票:0回答:1

我有一个非模态的 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)
    }
)

}

我没有提供位置代码或地址代码,因为本问题不需要此代码。

android kotlin android-webview overlay android-view
1个回答
0
投票

找到了一种禁用用户与 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 内的坐标,并允许与您需要响应事件的子项上方的区域相对应的坐标。

© www.soinside.com 2019 - 2024. All rights reserved.