Как реализовать BottomSheet в Material 3 Jetpack Compose Android

Я знаю, как реализовать BottomSheet в Material 2 Jetpack Compose, используя .

Но нетBottomSheetScaffoldв Материале 3. Также в официальных образцах ничего нет о BottomSheet.

3 ответа

ОБНОВЛЕНИЕ 23.02.2023

Начиная с Compose Material3 версии 1.1.0-alpha06 ModalBottomSheet теперь доступен как экспериментальный компонуемый (документы )


Я получил довольно похожие результаты, используя полноэкранный диалог с AnimatedVisibility, вот код, если интересно:

      // Visibility state for the dialog which will trigger it only once when called
val transitionState = remember {
    MutableTransitionState(false).apply {
        targetState = true
    }
}

Dialog(
    onDismissRequest = {} // You can set a visibility state variable to false in here which will close the dialog when clicked outside its bounds, no reason to when full screen though,
    properties = DialogProperties(
        // This property makes the dialog full width of the screen
        usePlatformDefaultWidth = false
    )
) {

    // Visibility animation, more information in android docs if needed
    AnimatedVisibility(
        visibleState = transitionState,
        enter = slideInVertically(
            initialOffsetY = { it },
            animationSpec = ...
        ),
        exit = slideOutVertically(
            targetOffsetY = { it },
            animationSpec = ...
        )
    )
) {

    Box(
        modifier = Modifier.fillMaxSize().background(color = ...)
    ) {
        // Your layout

        // This can be any user interraction that closes the dialog
        Button(
            transitionState.apply { targetState = false }
        ) ...
    }
}

Все это находится в составной функции, которая вызывается, когда выполняется действие пользовательского интерфейса для открытия указанного диалога, это не идеально, но работает.

Надеюсь, я смог помочь!

BottomSheetScaffold доступен в1.1.0-alpha08

см. https://developer.android.com/jetpack/androidx/releases/compose-material3#1.1.0-alpha08 .

Обновление за июль 2023 г.

BottomSheetScaffold из M2 теперь является частью M3 в качестве экспериментального API.

Вот пример того, как вы можете его использовать

      import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.runtime.rememberCoroutineScope

val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState()

BottomSheetScaffold(
    scaffoldState = scaffoldState,
    sheetPeekHeight = 128.dp,
    sheetContent = {
    Box(
        Modifier
            .fillMaxWidth()
            .height(128.dp),
        contentAlignment = Alignment.Center
    ) {
        Text("Swipe up to expand sheet")
    }
    Column(
        Modifier
            .fillMaxWidth()
            .padding(64.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Sheet content")
        Spacer(Modifier.height(20.dp))
        Button(
            onClick = {
                scope.launch { scaffoldState.bottomSheetState.partialExpand() }
            }
        ) {
            Text("Click to collapse sheet")
        }
    }
}) { innerPadding ->
    Box(Modifier.padding(innerPadding)) {
        Text("Scaffold Content")
    }
}

Или, если хотите, вы можете использовать автономный ModelBottomSheet , как показано в фрагменте кода ниже.

https://github.com/android/snippets/blob/7322f58994e9ade5ffee8e49f956e4a97339f384/compose/snippets/src/main/java/com/example/compose/snippets/layouts/MaterialLayoutSnippets.kt#L362

импорт:

      import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.material3.ModalBottomSheet

Код

      @OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BottomSheetDemo(title: String, modifier: Modifier = Modifier) {
    ModalBottomSheet(onDismissRequest = { /* Executed when the sheet is dismissed */ }) {
        // Sheet content
    }

    val sheetState = rememberModalBottomSheetState()
    val scope = rememberCoroutineScope()
    var showBottomSheet by remember { mutableStateOf(false) }
    Scaffold(
        floatingActionButton = {
            ExtendedFloatingActionButton(
                text = { Text(title) },
                icon = { Icon(Icons.Filled.Add, contentDescription = "") },
                onClick = {
                    showBottomSheet = true
                }
            )
        }
    ) { contentPadding ->
        // Screen content
        Box(modifier = Modifier.padding(contentPadding)) { /* ... */ }

        if (showBottomSheet) {
            ModalBottomSheet(
                onDismissRequest = {
                    showBottomSheet = false
                },
                sheetState = sheetState
            ) {
                // Sheet content
                Button(onClick = {
                    scope.launch { sheetState.hide() }.invokeOnCompletion {
                        if (!sheetState.isVisible) {
                            showBottomSheet = false
                        }
                    }
                }) {
                    Text("Hide bottom sheet")
                }
            }
        }
    }
}
Другие вопросы по тегам