Мне нужно использовать контекст сопрограммы для работы с modalState.show() или modalState.hide() в моем коде

@ExperimentalMaterialApi
@Composable
fun ModalBottomSheetLayoutDemo() {
    val modalState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)

    Button(modifier = Modifier.padding(16.dp), onClick = { modalState.show() }) {
        Text("Show Bottom Sheet")
    }

    ModalBottomSheetLayout(sheetState = modalState, sheetContent = {
        Text(
            modifier = Modifier.padding(start = 8.dp, top = 8.dp),
            text = "Title",
            fontWeight = FontWeight.Bold,
            style = typography.h5
        )
        Text(
            modifier = Modifier.padding(start = 8.dp, top = 8.dp),
            text = "Content example right here :)",
            style = typography.body1
        )
        Row(modifier = Modifier.align(Alignment.CenterHorizontally).padding(8.dp)) {
            Button(modifier = Modifier.padding(end = 8.dp), onClick = { modalState.hide() }) {
                Text("Cancel")
            }
            Button(onClick = { modalState.hide() }) {
                Text("Ok")
            }
        }
    }, sheetElevation = 8.dp) {}
}

Раньше он работал, а теперь требуется контекст сопрограммы, как выполнить контекст в составе Jetpack?

1
CoffeeBreak 27 Фев 2021 в 22:32

1 ответ

Лучший ответ

Вызовите rememberCoroutineScope(), сохраните его в переменной и используйте это для launch() вызовов show() и hide():

@ExperimentalMaterialApi
@Composable
fun ModalBottomSheetLayoutDemo() {
    val modalState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
    val sillyScope = rememberCoroutineScope()

    Button(modifier = Modifier.padding(16.dp), onClick = { sillyScope.launch { modalState.show() } }) {
        Text("Show Bottom Sheet")
    }

    ModalBottomSheetLayout(sheetState = modalState, sheetContent = {
        Text(
            modifier = Modifier.padding(start = 8.dp, top = 8.dp),
            text = "Title",
            fontWeight = FontWeight.Bold,
            style = typography.h5
        )
        Text(
            modifier = Modifier.padding(start = 8.dp, top = 8.dp),
            text = "Content example right here :)",
            style = typography.body1
        )
        Row(modifier = Modifier.align(Alignment.CenterHorizontally).padding(8.dp)) {
            Button(modifier = Modifier.padding(end = 8.dp), onClick = { modalState.hide() }) {
                Text("Cancel")
            }
            Button(onClick = { sillyScope.launch { modalState.hide() } }) {
                Text("Ok")
            }
        }
    }, sheetElevation = 8.dp) {}
}

AFAICT, вызов suspend используется потому, что API анимации в Compose UI используют сопрограммы, поэтому нам нужно применить подходящий CoroutineScope. rememberCoroutineScope() даст вам область видимости, которая хороша до тех пор, пока эта ветвь вашей композиции присутствует в той или иной форме.

2
CommonsWare 27 Фев 2021 в 19:36