如何防止ModalBottomSheet与系统按钮重叠?

huangapple go评论46阅读模式
英文:

How to prevent ModalBottomSheet from overlapping with the system buttons?

问题

I'm trying to add a ModalBottomSheet from Material3 into my app.
I have a main screen implemented like this:

@Composable
fun MainScreen() {

    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background
    ) {
        Scaffold(
            content = {},
            modifier = Modifier.fillMaxSize()
        )
    }
    SignInBottomSheet()
}

And SignInBottomSheet:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SignInBottomSheet() {

    ModalBottomSheet(
        onDismissRequest = {}
    ) {
        Column(
            modifier = Modifier.align(Alignment.CenterHorizontally)
        ) {
            Button(
                modifier = Modifier
                    .width(200.dp)
                    .height(70.dp)
                    .padding(bottom = 10.dp),
                onClick = { /*TODO*/ }
            ) {
                Text(
                    text = "Log in",
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.Bold
                )
            }
            Button(
                onClick = { /*TODO*/ },
                modifier = Modifier
                    .width(200.dp)
                    .height(70.dp)
                    .padding(bottom = 10.dp),
            ) {
                Text(
                    text = "Continue with Google",
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.Bold
                )
            }
        }
    }
}

The bottom sheet is visible when the app starts and when I tap outside of the bottom sheet, the bottom sheet is collapsed, but it stays at the bottom of the screen overlapping part of the system buttons.

I haven't added any remember object because I get the same behavior with the one, only difference is that the bottom sheet disappears after a moment (but still the snap is visible).

英文:

I'm trying to add a ModalBottomSheet from Material3 into my app.
I have a main screen implemented like this:

@Composable
fun MainScreen() {

    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background
    ) {
        Scaffold(
            content = {},
            modifier = Modifier.fillMaxSize()
        )
    }
    SignInBottomSheet()
}

And SignInBottomSheet:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SignInBottomSheet(
) {

    ModalBottomSheet(
        onDismissRequest = {}
    ) {
        Column(
            modifier = Modifier.align(Alignment.CenterHorizontally)
        ) {
            Button(
                modifier = Modifier
                    .width(200.dp)
                    .height(70.dp)
                    .padding(bottom = 10.dp),
                onClick = { /*TODO*/ }
            ) {
                Text(
                    text = "Log in",
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.Bold
                )
            }
            Button(
                onClick = { /*TODO*/ },
                modifier = Modifier
                    .width(200.dp)
                    .height(70.dp)
                    .padding(bottom = 10.dp),
            ) {
                Text(
                    text = "Continue with Google",
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.Bold
                )
            }
        }
    }
}

The bottom sheet is visible when the app starts and when I tap outside of the bottom sheet, the bottom sheet is collapsed, but it stays at the bottom of the screen overlapping part of the system buttons.

I haven't added any remember object because I get the same behavior with the one, only difference is that the bottom sheet disappears after a moment (but still the snap is visible).

Bellow are the images of the opened and closed bottom sheet (take a close look at the bottom of the screen).

如何防止ModalBottomSheet与系统按钮重叠?

如何防止ModalBottomSheet与系统按钮重叠?

答案1

得分: 2

这似乎在Compose Material 3版本1.2.0-alpha02中已解决。

请查看发行说明中的以下部分:

> 向ModalBottomSheet添加窗口插入参数。

然而,考虑到这是一个alpha库,不是每个人都会想要更新到它。

我为他们创建了一个问题跟踪器,以将修复内容回溯到1.1.0版本。

请查看:https://issuetracker.google.com/issues/284450382

英文:

Looks like this was resolved in Compose Material 3 version 1.2.0-alpha02.

Look under the following section in the release notes:

> Add window insets parameter to ModalBottomSheet.

However, given it's an alpha library, not everyone will want to update to it.

I created an issuetracker for them to backport the fix into 1.1.0.

See: https://issuetracker.google.com/issues/284450382

答案2

得分: 1

以下是您要翻译的部分:

"By Default they are not hiding the ModalBottomSheet, In document also they maintain the if condition to makes work around."

"By using if condition or Animated Visibility to fix the Bottom Sheet overlap issue."

"We need to maintain the state - var openBottomSheet by rememberSaveable { mutableStateOf(false) }"

"Change the state based on the Bottomsheet dimiss and open."

"Instead of If condition, we can use AnimatedVisibility also."

英文:

By Default they are not hiding the ModalBottomSheet, In document also they maintain the if condition to makes work around.

For your reference : https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#ModalBottomSheet(kotlin.Function0,androidx.compose.ui.Modifier,androidx.compose.material3.SheetState,androidx.compose.ui.graphics.Shape,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,androidx.compose.ui.unit.Dp,androidx.compose.ui.graphics.Color,kotlin.Function0,kotlin.Function1)

We need to maintain the state - var openBottomSheet by rememberSaveable { mutableStateOf(false) }

Change the state based on the Bottomsheet dimiss and open.

By using if condition or Animated Visibility to fix the Bottom Sheet overlap issue.

    var openBottomSheet by rememberSaveable { mutableStateOf(false) }
    var skipPartiallyExpanded by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()
    val bottomSheetState = rememberModalBottomSheetState(
        skipPartiallyExpanded = skipPartiallyExpanded
    )

// App content
Column(
    modifier = Modifier.fillMaxSize(),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.Center
) {
    Row(
        Modifier.toggleable(
            value = skipPartiallyExpanded,
            role = Role.Checkbox,
            onValueChange = { checked -> skipPartiallyExpanded = checked }
        )
    ) {
        Checkbox(checked = skipPartiallyExpanded, onCheckedChange = null)
        Spacer(Modifier.width(16.dp))
        Text("Skip partially expanded State")
    }
    Button(onClick = { openBottomSheet = !openBottomSheet }) {
        Text(text = "Show Bottom Sheet")
    }
}

// Sheet content
if (openBottomSheet) {
    ModalBottomSheet(
        onDismissRequest = { openBottomSheet = false },
        sheetState = bottomSheetState,
    ) {
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
            Button(
                // Note: If you provide logic outside of onDismissRequest to remove the sheet,
                // you must additionally handle intended state cleanup, if any.
                onClick = {
                    scope.launch { bottomSheetState.hide() }.invokeOnCompletion {
                        if (!bottomSheetState.isVisible) {
                            openBottomSheet = false
                        }
                    }
                }
            ) {
                Text("Hide Bottom Sheet")
            }
        }
        var text by remember { mutableStateOf("") }
        OutlinedTextField(value = text, onValueChange = { text = it })
        LazyColumn {
            items(50) {
                ListItem(
                    headlineContent = { Text("Item $it") },
                    leadingContent = {
                        Icon(
                            Icons.Default.Favorite,
                            contentDescription = "Localized description"
                        )
                    }
                )
            }
        }
    }
}

Instead of If condition, we can use AnimatedVisibility also.

huangapple
  • 本文由 发表于 2023年5月14日 08:22:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76245357.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定