我遇到了 Jetpack Compose 的问题,即在运行 Android 33 及更高版本的设备上,后按事件不会关闭底部工作表。有没有办法覆盖此行为或在 Jetpack Compose 中实现后按事件的自定义处理?我正在寻找解决这个特定问题的见解或解决方案。
为了了解更多上下文,我的项目使用导航组件进行导航。底部工作表在没有它的项目中工作得很好。
我尝试使用 Backhandler 来处理后压。
BackHandler {
coroutineScope.launch {
if (bottomSheetScaffoldState.isVisible) {
showBottomSheet = false
bottomSheetScaffoldState.hide()
} else {
showBottomSheet = true
bottomSheetScaffoldState.show()
}
}
}
这是我的底页
ModalBottomSheet(
onDismissRequest = { showBottomSheet = false },
shape = RoundedCornerShape(
topEnd = Constants.BOTTOM_SHEET_CORNER_RADIUS,
topStart = Constants.BOTTOM_SHEET_CORNER_RADIUS
),
sheetState = bottomSheetScaffoldState,
windowInsets = WindowInsets(0, 0, 0, 8),
) {
BoxWithConstraints(
Modifier
.navigationBarsPadding()
.padding(bottom = 10.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 10.dp)
.navigationBarsPadding()
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
}
.height(44.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = "Discard Changes",
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Normal,
fontSize = 15.sp,
color = colorResource(
id = R.color.system_red
),
textAlign = TextAlign.Start,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
coroutineScope
.launch {
bottomSheetScaffoldState.hide()
}
.invokeOnCompletion {
if (!bottomSheetScaffoldState.isVisible) {
showBottomSheet = false
keyboard?.show()
}
}
}
.height(44.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = "Keep Editing",
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Normal,
fontSize = 15.sp,
color = if (!isSystemInDarkTheme()) colorResource(id = R.color.black) else colorResource(
id = R.color.white
),
textAlign = TextAlign.Start,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
)
}
}
}
}
此解决方案适用于 Android 12 及更低版本的设备,但不适用于 API 33 及更高版本的设备。
onBackPressed 在 API 33 中已被弃用,以上版本使用 getOnBackInvokedDispatcher 代替。 https://developer.android.com/guide/navigation/custom-back/predictive-back-gesture#kotlin
if (BuildCompat.isAtLeastT()) {
onBackInvokedDispatcher.registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT
) {
/**
* onBackPressed logic goes here. For instance:
* Prevents closing the app to go home screen when in the
* middle of entering data to a form
* or from accidentally leaving a fragment with a WebView in it
*
* Unregistering the callback to stop intercepting the back gesture:
* When the user transitions to the topmost screen (activity, fragment)
* in the BackStack, unregister the callback by using
* OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
* (https://developer.android.com/reference/kotlin/android/window/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
*/
}
}