如何在 Jetpack compose 中制作可重用的组件?

Posted

技术标签:

【中文标题】如何在 Jetpack compose 中制作可重用的组件?【英文标题】:How to make reusable components in Jetpack compose? 【发布时间】:2021-12-21 09:45:02 【问题描述】:

我正在尝试创建一个 TextField 可重用组件,所以我这样做了

@Composable
fun TextFieldComponent(state: Any, placeholder: String) 
    TextField(
        value = state,
        onValueChange =  textFieldValue -> state = textFieldValue ,
        placeholder =  Text(placeholder, color = MaterialTheme.colors.secondary) 
    )

但我遇到了这些错误

这就是我调用组件的方式

val textFieldState by rememberSaveable  mutableStateOf("") 
TextFieldComponent(state = textFieldState, placeholder = "Email")

那么有什么解决办法吗?

【问题讨论】:

在您的TextFieldComponent() 中,state 不能是Any。它需要是TextField() 支持的类型。 【参考方案1】:

只需将state 变成MutableState<String>,这样您就可以在函数内部对其进行修改:

@Composable
fun TextFieldComponent(state: MutableState<String>, placeholder: String) 
    TextField(
        value = state.value,
        onValueChange =  textFieldValue -> state.value = textFieldValue ,
        placeholder =  Text(placeholder, color = MaterialTheme.colors.secondary) 
    )

但是,通常最好为可组合函数提供一个值和一个更改侦听器:

@Composable
fun TextFieldComponent2(value: String, onValueChange: (String) -> Unit, placeholder: String) 
    TextField(
        value = value,
        onValueChange =  textFieldValue -> onValueChange(textFieldValue) ,
        placeholder =  Text(placeholder, color = MaterialTheme.colors.secondary) 
    )

这样的解决方案更加灵活,因为调用者可以很容易地提供任何值变化的行为(感谢@Jakoss)

【讨论】:

请不要。这违反了撰写 - 提升状态的最核心规则。该函数应该获得一个 onValueChange 作为参数 @Jakoss 我远不是 Compose 专家,但你为什么认为它没有被提升? TextFieldComponent 在这里没有自己的状态。它从调用者那里接收它。 MutableState 在这里充当值提供者和值更改回调,我相信它实际上与单独接收它们相同。官方文档甚至提供了关于传递给可组合函数的状态持有者的示例。有什么不同? 不同之处在于调用者无法以任何方式控制该状态。它只是为数据提供了一个包。这不是可重用组合的模式,我在材料或 ui 库中没有看到一个模式。它只是没有那么灵活,而且 imo 它只是劣质的。它基本上做同样的事情,但让调用者控制进程 是的,我同意,更改监听器更灵活。我提供这样的解决方案只是因为 OP 的原始解决方案几乎是可行的。但你是对的——我至少应该提一下,这不是通常的做法。谢谢,我更新了答案。

以上是关于如何在 Jetpack compose 中制作可重用的组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在jetpack compose中定义不同的屏幕

在 Jetpack Compose 中单击时如何禁用涟漪效应

如何在 Jetpack Compose 中添加保证金?

如何在 Jetpack Compose 中使用小部件?

如何在Jetpack Compose中更改topBar对应的屏幕

如何在 Jetpack Compose 的 LazyColumn/LazyRow 中禁用和启用滚动?