组合状态提升中的类型不匹配

Type mismatch in compose state hoisting

我正在尝试让一个 属性 绑定在 ViewModel@Composable 之间。

我收到以下错误

Type mismatch. 
Required:String 
Found:MutableState<String.Companion>

我不明白我做错了什么。

//Reusable input field
@Composable
fun MyTextField(
    value: String,
    onValueChange: (String) -> Unit,
    placeHolder: String
    ) {
    OutlinedTextField(
        value = value,
        onValueChange = onValueChange,
        placeholder = {Text(placeHolder)},
    )
}


// ViewModel
class MyViewModel : ViewModel () {
    var MyVariable = mutableStateOf(String)
}


// stateful comp
@Composable
fun MyScreen(
    viewModel: MyViewModel = MyViewModel()
) {
     MyContent(
        myVariable = vm.myVariable,
        setMyVariable = { vm.myVariable = it }
    )
}

// stateless Comp
@Composable
fun MyContent(
    myVariable: String,
    setMyVariable: (String) -> Unit
)
    {
        Column() {
    
            MyTextField(value = myVariable, onValueChange = setMyVariable, placeholder = "Input Something")

            Text("Your variable is $myVariable" )
    }


替换

MyContent(
    myVariable = vm.myVariable,
    setMyVariable = { vm.myVariable = it }
)

MyContent(
    myVariable = vm.myVariable.value,
    setMyVariable = { vm.myVariable.value = it }
)

你需要像这样定义你的变量

val MyVariable = mutableStateOf<String>("initial value here")

您正在将变量初始化为 MutableState<T> 类型 data-holder。

你在问题中发布的内容甚至无法编译,但我认为这是你在实际代码中所做的

var myVar = mutableStateOf ("")

现在,mutableStateOf("") returns 一个 MutableState<String> 类型的对象,您将在您的方法中传递它。

另一方面,您的方法需要一个 String 类型的对象,而不是 MutableState<String>。因此,您可以从变量中提取值并将其传递,

myVar.value

或者以首选方式使用 kotlin 属性 委托。

像这样初始化变量

var myVar by mutableStateOf ("")

by 关键字充当初始化程序和 returns 的 String 值而不是 MutableState<T> 的委托。这更新和触发重组就像它的其他对应物一样,但代码更清晰,并将样板文件保持在最低限度。

此外,您似乎对 compose 和 kotlin 还很陌生,因此请考虑通过 Compose 途径学习基础知识。只需查找,第一位官方 Android 开发人员 link 将带您到那里。

编辑:最终答案

视图模型

ViewModel{
 var v by mutableStateOf ("")
 fun setV(v: String) {
   this.v = v
 }
}

可组合调用站点

MyComposable(
 value = viewModel.v
 onValueChange = viewModel::setV
)

可组合声明

fun MyComposable (
 value: String,
 onValueChange: (String) -> Unit
) {
 TextField (
  value = value
  onValueChange = onValueChange
 )
}

这是正确的 state-hoisting linking,其中状态变量已正确更新,因此读起来很好。另外,先生,如果您真的通读了文档并参加了代码实验室,您就会知道 state-hoisting 是什么。我是认真的,参加代码实验室(在 Compose 路径中)。这就是你的问题多次被否决的原因,因为你使用像 state-hoisting 这样的术语就好像你理解它一样,但是你没有它所促进的一半实施。