LazyColumn 中每个项目的状态提升

时间:2021-07-20 15:05:15

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

我已经完成了 this 代码实验室。在第 7 步中,当单击单行文本时,它会改变其颜色,但函数不会跟踪它,这意味着重新组合后它会消失。

我想让列表记住单个项目的颜色,因此我将状态提升移动到 NameList 函数级别。 不幸的是它不起作用。

错误在哪里?

    @Composable
fun NameList(names: List<String>, modifier: Modifier = Modifier) {

    LazyColumn(modifier = modifier) {
        items(items = names) { name, ->
            val isSelected  = remember { mutableStateOf(false)}
            Greeting(name = name,isSelected.value){ newSelected -> isSelected.value = newSelected}
            Divider(color = Color.Black)
        }
    }
}

@Composable
fun Greeting(name: String,isSelected : Boolean, updateSelected : (Boolean) -> Unit) {

    val backgroundColor by animateColorAsState(if (isSelected) Color.Red else Color.Transparent)
    Text(
        modifier = Modifier
            .padding(24.dp)
            .background(color = backgroundColor)
            .clickable(onClick = { updateSelected(!isSelected)}),
        text = "Hello $name",

        )
}

1 个答案:

答案 0 :(得分:1)

您应该将选择状态提升到 NameList 函数的调用者。

@Composable
fun MyScreen() {
    // Fake list of names
    val namesList = (1..100).map { "Item $it" }
    // Here, we're keeping the selected positions. 
    // At the beginning, all names are not selected.
    val selection = remember {
        mutableStateListOf(*namesList.map { false }.toTypedArray())
    }
    
    NameList(
        // list of names
        names = namesList, 
        // list of selected items
        selectedItems = selection,
        // this function will update the list above
        onSelected = { index, selected -> selection[index] = selected },
        // just to occupy the whole screen 
        modifier = Modifier.fillMaxSize()
    )
}

然后,您的 NameList 将如下所示:

@Composable
fun NameList(
    names: List<String>,
    selectedItems: List<Boolean>,
    onSelected: (index: Int, selected: Boolean) -> Unit,
    modifier: Modifier = Modifier
) {
    LazyColumn(modifier = modifier) {
        itemsIndexed(items = names) { index, name ->
            Greeting(
                name = name, 
                isSelected = selectedItems[index],
                updateSelected = { onSelected(index, it) }
            )
            Divider(color = Color.Black)
        }
    }
}

Greeting 函数没有任何变化。

结果如下:

enter image description here