java .lang.IllegalStateException: для композиции требуется активный контекст композиции (Android Jetpack Compose) - PullRequest
1 голос
/ 22 января 2020

Попытка показать AlertDialog с помощью Jetpack Compose, но приложение аварийно завершает работу при вызове функции AlertDialog с ошибкой

java .lang.IllegalStateException: для композиции требуется активный контекст композиции

Пожалуйста, найдите код ниже,

@Composable
fun homeScreenCompose() {

    Align(
        alignment = Alignment.Center
    ) {
        Column(
            arrangement = Arrangement.Center,
            modifier = Spacing(16.dp),
            children = {

                Button(
                    modifier = Height(50.dp) wraps Expanded,
                    text = "Alert Dialog", onClick = {
                        showAlertDialog()
                    }, style = OutlinedButtonStyle(
                        Border(color = Color.Red, width = 1.dp),
                        shape = RoundedCornerShape(50), //50% percent
                        contentColor = Color.Red,
                        color = Color.White,
                        elevation = Dp(4f)
                    )
                )
            }
        )
    }

}

@Composable
fun showAlertDialog() {
    val openDialog = +state { true }
    if (openDialog.value) {
        AlertDialog(
            onCloseRequest = {
            },
            title = {
                Text(text = "Logout")
            },
            text = {
                Text("Are you sure you have to logout?")
            },
            confirmButton = {
                Button("Yes", onClick = {
                    openDialog.value = false
                })
            },
            dismissButton = {
                Button("No", onClick = {
                    openDialog.value = false
                })
            },
            buttonLayout = AlertDialogButtonLayout.Stacked
        )
    }

}

Не в состоянии выяснить, почему происходит сбой и какое решение для этого, любая помощь будет оценена.

Спасибо вы.

1 Ответ

3 голосов
/ 22 января 2020
  1. Создает класс данных для модели состояния, и его не нужно отмечать аннотацией @Model.
  2. Само начальное состояние создается внутри функции @Composable с использованием состояния +.
  3. Видимость диалогового окна определяется свойством visible модели, полученной путем вызова свойства value.
  4. Это свойство также можно установить для нового неизменяемого объекта, как это происходит в onClick. обеих кнопок. Первый прячется, второй - закрывает диалог. Диалоговое окно можно открыть, нажав кнопку Ok, определенную внутри той же функции @Composable.

При попытке создать состояние вне этой функции возникает ошибка:

java .lang.IllegalStateException: для композиции требуется активный контекст композиции.

Контекст может быть получен путем присвоения значения функции setContent {} в onCreateView, но как использовать это, например, в Presenter или другом классе, отличном от Fragment или Activity, для изменения состояния все еще неясно.

Проверьте пример ниже

 data class DialogVisibleModel(val visible: Boolean, val dismissPushed: Boolean = false)
    ...
 @Composable
 fun homeScreenCompose() {

   Column {
        SideBySideAlertDialogSample()
   }

 }

@Composable
fun SideBySideAlertDialogSample() {
    val openDialog = +state { DialogVisibleModel(false) }

    Button(text = "Ok", onClick = { openDialog.value = DialogVisibleModel(true) })

    if (openDialog.value.visible) {
        AlertDialog(
            onCloseRequest = {
                // Because we are not setting openDialog.value to false here,
                // the user can close this dialog only via one of the buttons we provide.
            },
            title = {
                Text(text = "Title")
            },
            text = {
                Text("This area typically contains the supportive text" +
                        " which presents the details regarding the Dialog's purpose.")
            },
            confirmButton = {
                Button("Confirm", onClick = {
                    openDialog.value = DialogVisibleModel(false)
                })
            },
            dismissButton = {
                if (!openDialog.value.dismissPushed)
                    Button("Dismiss", onClick = {
                        openDialog.value = DialogVisibleModel(true, true)
                    })
                else {
                    //hidden
                }
            },
            buttonLayout = AlertDialogButtonLayout.SideBySide
        )
    }
}
...