【问题标题】:@composable invocations can only happen from the context of an @composable function@composable 调用只能在 @composable 函数的上下文中发生
【发布时间】:2020-12-27 06:41:12
【问题描述】:

我试图在单击工具栏操作时显示 Toast 消息,但出现此错误

@composable 调用只能在一个上下文中发生 @可组合函数

代码:

@Composable
fun Toolbar() {
    TopAppBar(title = { Text(text = "Jetpack Compose") }, navigationIcon = {
        IconButton(onClick = {}) {
            Icon(Icons.Filled.Menu)
        }
    }, actions = {
        IconButton(onClick = {
            showMessage(message = "test")
        }) {
            Icon(vectorResource(id = R.drawable.ic_baseline_save_24))
        }
    })
}

@Preview
@Composable
fun ToolbarPreview(){
    Toolbar()
}

@Composable
fun showMessage(message:String){
    Toast.makeText(ContextAmbient.current, message, Toast.LENGTH_SHORT).show()
}

【问题讨论】:

    标签: android kotlin android-jetpack android-jetpack-compose


    【解决方案1】:

    onClick 参数不接受可组合函数。 去掉showMessage中的@Composable注解。
    使用类似的东西:

    @Composable
    fun Toolbar() {
    
        val context = LocalContext.current
    
        TopAppBar(title = {},
                actions = {
            IconButton(onClick = {
                showMessage(context, message = "test")
            }){}
        })
    }
    
    fun showMessage(context: Context, message:String){
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
    }
    

    【讨论】:

    • 你为什么不能这样做呢?这是任何其他框架中的基本 UI 行为?如何在 onClick() 事件中显示视图或更改视图状态?
    • 好点,不幸的是,从嵌套在 Box 中的 LazyColumn 调用显示消息时,我仍然遇到问题。是因为 compose 的树特性吗?
    • @user901790:你的 UI 应该基于状态数据组成,这意味着 UI 永远不会被直接修改。相反,要“修改” UI,您需要修改状态,这反过来会导致 UI 重新组合并在视觉上发生变化。
    • 顺便说一句。 ContextAmbient 现在称为 LocalContext
    • @m.reiter 感谢您的反馈。答案已更新。
    【解决方案2】:

    我遇到了同样的错误,我的解决方案是在我传递另一个可组合函数的方法中的参数中添加 @Composable 注释。

    例子:

    navigationIcon: @Composable () -> Unit
    

    【讨论】:

      【解决方案3】:

      你的意思是这样的?

      @Composable
      fun MyTopAppBar(
              title: String,
              actionItem: TopBarActionItem,
              navigationClick: (@Composable () -> Unit)? = null) {}
      

      你如何调用navigationClick? invoke() 方法本身不可组合,再次报错。

      你不能使用navigationClick?.invoke()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-05
        • 1970-01-01
        相关资源
        最近更新 更多