如何将 Jetpack Compose 中的警报对话框放置在屏幕底部。另外,设置透明背景。
从弗拉基米尔的回答中得到的想法,最适合我的解决方案是从对话框中获取对窗口的引用并设置所需的重力。
Dialog(
onDismissRequest = [...],
properties = [...],
) {
val dialogWindowProvider = LocalView.current.parent as DialogWindowProvider
dialogWindowProvider.window.setGravity(Gravity.BOTTOM)
[...]
}
演员阵容不应该成为问题,但当然,可以安全演员阵容以防止出现不愉快的意外。
谢谢@alekseyHunter 和@johann。我可以使用自定义布局修改器来实现这一点。
用于定位警报对话框的自定义修饰符
enum class CustomDialogPosition {
BOTTOM, TOP
}
fun Modifier.customDialogModifier(pos: CustomDialogPosition) = layout { measurable, constraints ->
val placeable = measurable.measure(constraints);
layout(constraints.maxWidth, constraints.maxHeight){
when(pos) {
CustomDialogPosition.BOTTOM -> {
placeable.place(0, constraints.maxHeight - placeable.height, 10f)
}
CustomDialogPosition.TOP -> {
placeable.place(0,0,10f)
}
}
}
}
在警报对话框中实现为
AlertDialog( ..., modifiers = Modifiers.customDialogModifier(CustomDialogPosition.BOTTOM))
{
// block
})
看起来很简单。
Box(Modifier.fillMaxSize()) {
Column() {
/* Content */
}
/* Box alert */
Box(
Modifier
.padding(horizontal = 32.dp, vertical = 16.dp)
.fillMaxWidth()
.background(Color.Transparent, RoundedCornerShape(8.dp))
.border(2.dp, Color.LightGray, RoundedCornerShape(8.dp))
.align(Alignment.BottomCenter)
) {
Text(
text = "Alert",
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
textAlign = TextAlign.Center,
color = Color.Black
)
}
}
仅供参考,一种获得带有填充(以及对齐)的对话框的简单方法,而不影响“在外部单击时关闭”(对齐中
Box
解决方案的问题):
fun MyTopAlignedDialog(
onDismissRequest: () -> Unit,
) {
Dialog(
onDismissRequest = onDismissRequest,
//...
) {
(LocalView.current.parent as DialogWindowProvider).apply {
window.setGravity(Gravity.TOP)
window.attributes = window.attributes.apply {
y = DialogTopPadding
}
}
// Dialog content...
}
}
internal const val DialogTopPadding = 192
@Rameshbabu 提供的解决方案按预期更改了对话框的位置。但是,正如评论中提到的,对话框因此变为“全屏”,并且无法通过点击覆盖层将其关闭。
我找到了另一个棘手的解决方案。您可以复制
androidx.compose.ui.window.AndroidDialog.kt
附带的"androidx.compose.ui"
的源代码。通过这样做,您将能够直接访问对话框的窗口并更改其重力和其他参数。
最简单的方法是在
androidx.compose.ui.window.DialogWrapper
类中添加一些代码。例如在 init 函数中:
private class DialogWrapper(
private var onDismissRequest: () -> Unit,
...
) : Dialog(ContextThemeWrapper(...){
...
init {
val window = window ?: error("Dialog has no window")
window.requestFeature(Window.FEATURE_NO_TITLE)
window.setBackgroundDrawableResource(android.R.color.transparent)
window.setGravity(Gravity.TOP) // This to be added
希望 Jetpack Compose 团队将来能够使撰写对话框更加可定制。