首页 > 解决方案 > java.lang.IllegalStateException:组合需要一个活动组合上下文(Android Jetpack Compose)

问题描述

尝试使用 Jetpack Compose 显示 AlertDialog,但应用程序在调用 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
        )
    }

}

无法弄清楚它为什么会崩溃以及解决方案是什么,我们将不胜感激。

谢谢你。

标签: androidkotlinillegalstateexceptionandroid-jetpackandroid-jetpack-compose

解决方案


  1. 为状态模型创建一个数据类,它不必用@Model 注解标记。
  2. 初始状态本身是在 @Composable 函数中使用 + 状态创建的。
  3. 对话框的可见性由调用 value 属性获得的模型的 visible 属性决定。
  4. 这个属性也可以设置为一个新的不可变对象,就像两个按钮的 onClick 一样。第一个隐藏自己,第二个 - 关闭对话。可以通过单击在同一 @Composable 函数中定义的 Ok 按钮重新打开该对话框。

尝试在此函数之外创建状态时,会发生错误:

java.lang.IllegalStateException:组合需要一个活动的组合上下文。

上下文可以通过在 中分配setContent {}函数的值来获得onCreateView,但是如何使用它,例如在 Presenter 或除Fragmentor之外的其他类中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
        )
    }
}

推荐阅读