如何从 Activity 中的 XML 按钮切换 ComposeView 中的下拉菜单?

问题描述 投票:0回答:1

我目前正在将 XML 布局迁移到 Jetpack Compose。

我开发了一个通用的

androidx.compose.material3.DropdownMenu
Compose 函数,我希望在我当前的 Android 项目中的任何地方使用它,并通过单击 XML
Button
显示(展开)它。

这是我当前的代码,它确实可以按预期工作。但是我不确定这是否是最好/正确的方法。

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_second)

        val button = findViewById<Button>(R.id.showDropDown)

        val showDropDownMenu = mutableStateOf(true)

        button.setOnClickListener {
            showDropDownMenu.value = true
        }

        findViewById<ComposeView>(R.id.composeDropDownMenuOuter).apply {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                DropDownMenuUi(showDropDownMenu)
            }
        }
    }

DropDownMenuUi
可组合项类似于:

    @Composable
    fun DropDownMenuUi(showDropDownMenu: MutableState<Boolean>) {
        val expanded by remember { mutableStateOf(showDropDownMenu) }
        DropdownMenu(
           modifier = ddm.modifier ?: Modifier.padding(start = 10.dp, end = 10.dp),
           expanded = expanded.value,
           onDismissRequest = { expanded.value = false },
           offset = ddm.offset ?: DpOffset(0.dp, 0.dp)
        ) {
           ...
           ...
           ...
           ...
        }
        ...
        ...
        ...

我主要关心的是使用

val showDropDownMenu = mutableStateOf(true)
,这对于撰写来说可以吗? 我可以采用更“组合”的方法吗?

android android-jetpack-compose
1个回答
1
投票

虽然代码有效,但从 Activity 中的

mutableStateOf()
在可组合项中创建
mutableStateOf()
是多余的。另外,不建议直接从嵌套可组合项覆盖
MutableState
。相反,您的可组合项应该有一个回调。

另一个最近的转变是,当我们不在可组合范围内时,我们应该更喜欢

MutableStateFlow
(来自Kotlin库)而不是
mutableStateOf
(来自Compose库)。通过这样做,我们将 ViewModel 或 Activity 代码与可组合库解耦。然后,您可以使用
MutableStateFlow
 在您的可组合项中收集 
collectAsStateWithLifecycle()

请尝试重构您的

DropDownMenuUi
可组合项,如下所示:

@Composable
fun DropDownMenuUi(showDropDownMenu: Boolean, onDismiss: () -> Unit) {
    DropdownMenu(
        //...
        expanded = showDropDownMenu,
        onDismissRequest = onDismiss,
        // ...
    ) {
        //...
    }
}

然后,在您的

onCreate
函数中,声明一个
MutableStateFlow
,如下所示:

val showDropDownMenuState = MutableStateFlow(true)
button.setOnClickListener {
    showDropDownMenuState.value = true
}

最后,按如下方式调用您的可组合项:

setContent {

    // use below variable for reading the showDropDownMenuState
    val showDropDownMenu by showDropDownMenuState.collectAsStateWithLifecycle()

    DropDownMenuUi(
        showDropDownMenu = showDropDownMenu,
        onDismiss = {
            showDropDownMenuState.value = false
        }
    )
}
© www.soinside.com 2019 - 2024. All rights reserved.