Jetpack Compose 中 LazyVerticalGrid 中的所选项目丢失状态

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

我的应用程序中有一个网格列表,我在单击卡片时更改背景颜色。在我滚动之前它似乎工作正常。我知道当隐藏项目再次可见时,compose 会重新绘制隐藏元素。我在管理列表项的状态时遇到问题。

data class MonthFee(var isPaid :Boolean,var month :String,var monthIndex :Long)


@OptIn(ExperimentalMaterialApi::class)
@Composable
fun MonthSelectList2(
monthList: List<MonthFee>,
color: Color,
onMonthSelect: (list: List<MonthFee>) -> Unit) {

val selectedItems = remember { mutableStateListOf<MonthFee>() }

LazyVerticalGrid(
    userScrollEnabled = true,
    modifier = Modifier.background(color = MaterialTheme.colors.background.copy(0.6f)),
    columns = GridCells.Adaptive(150.dp)
) {
    items(items = monthList,key = {it.monthIndex}) { item ->

        val isSelected = selectedItems.contains(item)
        val cardBgColor = remember { 
          mutableStateOf(item.isPaid.getActivatedColor(color))
        }

        Card(backgroundColor = MaterialTheme.colors.background.copy(1f),
            onClick = {

                if (!item.isPaid) {
                    if (isSelected) {
                        selectedItems.remove(item)
                        cardBgColor.value = Color.LightGray
                    } else {
                        selectedItems.add(item)
                        cardBgColor.value = color.copy(0.65f)
                    }
                    onMonthSelect(selectedItems.toList())
                }

            }) {
            Box{
                Column(
                    modifier = Modifier.background(color = cardBgColor.value)
                ) {
                    Text(text = item.month)
                }
                if (item.isPaid) {
                    Image(
                        painter = painterResource(id = R.drawable.green_tick),
                        modifier = Modifier
                            .requiredSize(25.dp)
                            .padding(start = 0.dp, end = 0.dp, top = 0.dp, bottom =0.dp)
                            .clip(CircleShape),
                        contentDescription = ""
                    )
                }
            }}}}}

上面使用的扩展

fun Boolean.getActivatedColor(color: Color): Color {
return if (this) {
    color
} else {
    Color.LightGray
}}

我尝试提升状态,使用rememberSaveable{},但UI在滚动时不持久。 参考

android android-studio user-interface android-jetpack-compose android-jetpack
1个回答
0
投票

要保持您的卡片状态,即使该项目滚动到屏幕之外。你需要:

  • 创建一个布尔值列表,全部设置为 false,元素数量等于列表
    monthList.size
val selectedItems = remember {
    mutableStateListOf<Boolean>().apply {
        addAll(List(monthList.size) { false })
    }
}
  • 使用
    itemsIndexed
    而不是
    items
    来获取相应列表索引的布尔值。
itemsIndexed(selectedItems) { index, isSelected ->
    YourLayout(
        isSelected = isSelected,
        onSelectedChanged = {
            selectedItems[index] = isSelected
        }
    )
}
  • 并在您的
    YourLayout
    中声明一个
    remember
    变量来跟踪更改布尔值。
 var selected by remember {
     mutableStateOf(isSelected)
 }
 LaunchedEffect(key1 = isSelected) {
     onSelectedChanged(isSelected)
 }

这是所有代码示例:

    @Composable
    fun MonthSelectList2(
        monthList: List<MonthFee>,
        color: Color,
        onMonthSelect: (list: List<MonthFee>) -> Unit
    ) {
        val selectedItems = remember {
            mutableStateListOf<Boolean>().apply {
                addAll(List(monthList.size) { false })
            }
        }

        LazyVerticalGrid(
            userScrollEnabled = true,
            modifier = Modifier.background(color = Color.Black),
            columns = GridCells.Adaptive(150.dp)
        ) {

            itemsIndexed(selectedItems) { index, isSelected ->
                YourLayout(
                    isSelected = isSelected,
                    onSelectedChanged = {
                        selectedItems[index] = isSelected
                    }
                )
            }
        }
    }
}


@Composable
fun YourLayout(
    isSelected: Boolean,
    onSelectedChanged: (Boolean) -> Unit
) {
    var selected by remember {
        mutableStateOf(isSelected)
    }

    LaunchedEffect(key1 = isSelected) {
        onSelectedChanged(isSelected)
    }

    // Card....
}
© www.soinside.com 2019 - 2024. All rights reserved.