代码之家  ›  专栏  ›  技术社区  ›  Bob Rasner

使用数据类保存TextField的值和onValueChange参数时,不会出现TextField按键

  •  0
  • Bob Rasner  · 技术社区  · 1 年前

    我试图通过在列表中迭代来创建同一TextField的多个实例,而不是直接创建每个实例。问题是,TextField中没有出现任何按键。

    首先,我将value和onValueChange参数放入一个名为“TextFieldClass”的数据类中。

    data class TextFieldClass(
        var textValue: String,
        var onTextChange: (String) -> Unit,
        val label : String
    )
    

    然后,我制作了一个列表,其中包含两个名为“textFieldClasses”的“TextFieldClass”实例

    val textFieldClasses = listOf(
        TextFieldClass(
            textValue = "",
            onTextChange = { newValue ->},
            label = "Text Field 1"
        ),
        TextFieldClass(
            textValue = "",
            onTextChange = { newValue ->},
            label = "Text Field 2"
        )
    

    )

    然后,我创建了一个包含名为“TextFieldListItem”的TextField UI的可组合对象。值、onValueChange和标签参数将传递到构造函数中。

    Composable
    fun TextFieldListItem(
        text: String,
        onTextChange: (String) -> Unit,
        label: String
    ) {
        TextField(
            value = text,
            onValueChange = { onTextChange(it) },
            label = { Text(label) }
        )
    

    }

    然后,我创建了另一个可组合对象来包含“TextFieldListItem”,并迭代名为“TextFieldList”的“textFieldClasses”列表。很抱歉,如果使用列表太多会造成混淆。

    @Composable
    fun TextFieldList() {
        Column {
            textFieldClasses.forEach{ textFieldTests ->
                TextFieldListItem(
                    text = textFieldTests.textValue,
                    onTextChange = {textFieldTests.onTextChange(it)},
                    label = textFieldTests.label
                    )
            }
        }
    }
    

    最后,我把这一切都放在了主活动中。

    然而,问题仍然存在。按键未出现在文本字段上。它只是空着。

    有人知道如何解决这个问题吗?

    0 回复  |  直到 1 年前
        1
  •  0
  •   BenjyTec    1 年前

    这里的第一个问题是,你基本上在这里声明了一个空函数:

    TextFieldClass( 
        textValue = "",
        onTextChange = { newValue ->},  // empty function doing nothing
        label = "Text Field 1"
    )
    

    然后,您将该空函数分配给 onTextChange TextField 。所以你实际上需要这样的东西(这也行不通,我将在下面解释):

    val onTextChange: (String) -> Unit = { textValue = it }  // ALSO NOT WORKING!
    

    这里的第二个问题是,您正在使用 var 对于您的房产 TextFieldClass 数据类。Jetpack Compose无法观察到可变变量的变化 var 糖尿病。你应该把它改成 val 并使用以下命令更新数据类的属性 copy 功能。

    由于数据类的属性需要是不可变的,以便Compose检测更改,因此定义 onTextChange 功能在你 文本字段类 要更新 textValue 不起作用。我建议你重构你的代码。

    首先,使数据类中的所有属性不可变,并删除 onTextChange 财产:

    data class TextFieldClass(
        val textValue: String,
        val label : String
    )
    

    然后,您需要申报您的 textFieldClasses Compose可以检测到列表中的一个项目何时被修改。您可以通过使用以下命令声明列表来实现这一点 mutableStateListOf 如下:

    val textFieldClasses = remember {
        mutableStateListOf(
            TextFieldClass(
                textValue = "",
                label = "Text Field 1"
            ),
            TextFieldClass(
                textValue = "",
                label = "Text Field 2"
            )
        )
    }
    

    最后,一旦TextField中的值发生变化,您需要更新 text字段类 使用 复制 功能:

    textFieldClasses.forEachIndexed { position, textFieldTests ->
        TextFieldListItem(
            text = textFieldTests.textValue,
            onTextChange = { newText ->
                // update data class instance using copy and then update value in list
                textFieldClasses[position] = textFieldClasses[position].copy(textValue = newText)
            },
            label = textFieldTests.label
        )
    }
    

    然后,当您在其中键入内容时,每个TextField都应该被正确地重新组合。