android 单一选择-在惰性列中取消选择

oipij1gg  于 2022-12-02  发布在  Android
关注(0)|答案(2)|浏览(125)

问题:::我想创建一个惰性列,在其中一次只能选择或取消选择一个选项。现在,每当我单击惰性列中的行组件时,所有行都将被选中。
代码:

@Composable
fun LazyColumnWithSelection() {

    var isSelected by remember {
        mutableStateOf(false)
    }
    
    var selectedIndex by remember { mutableStateOf(0) }
    
    val onItemClick = { index: Int -> selectedIndex = index }

    LazyColumn(
        modifier = Modifier.fillMaxSize(),
    ) {
        items(100) { index ->

            Row(modifier = Modifier
                .fillMaxWidth()
                .clickable {
                    onItemClick.invoke(index)
                    if (selectedIndex == index) {
                        isSelected = !isSelected
                    }
                }
                .padding(16.dp),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically) {
                Text(text = "Item $index", modifier = Modifier.padding(12.dp), color = Color.White)
                if (isSelected) {
                    Icon(imageVector = Icons.Default.Check,
                        contentDescription = "Selected",
                        tint = Color.Green,
                        modifier = Modifier.size(20.dp))
                }
            }

        }
    }
}

当前结果:
点击前-〉

点击后-〉

你可以看到所有的项目都被选中,但我应该能够选择或取消选择一个项目的时间,而不是所有。
我试图使用remember state来选择,但是我想我在索引选择或者if语句中做错了什么。

n3ipq98p

n3ipq98p1#

这应该能给予你领先一步。
这里有4组件:

  • 数据类别
  • 类别状态保持器
  • 可组合项目
  • 可组合项列表

ItemData

data class ItemData(
      val id : Int,
      val display: String,
      val isSelected: Boolean = false
  )

State holder

class ItemDataState {

    val itemDataList = mutableStateListOf(
        ItemData(1, "Item 1"),
        ItemData(2, "Item 2"),
        ItemData(3, "Item 3"),
        ItemData(4, "Item 4"),
        ItemData(5, "Item 5")
    )

    // were updating the entire list in a single pass using its iterator
    fun onItemSelected(selectedItemData: ItemData) {
        val iterator = itemDataList.listIterator()

        while (iterator.hasNext()) {
            val listItem = iterator.next()

            iterator.set(
                if (listItem.id == selectedItemData.id) {
                    selectedItemData
                } else {
                    listItem.copy(isSelected = false)
                }
            )
        }
    }
}

ItemComposable

@Composable
fun ItemDisplay(
    itemData: ItemData,
    onCheckChanged: (ItemData) -> Unit
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(80.dp)
            .border(BorderStroke(Dp.Hairline, Color.Gray)),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween
    ) {

        Text(text = if (itemData.isSelected) "I'm selected!" else itemData.display)

        Checkbox(
            checked = itemData.isSelected,
            onCheckedChange = {
                onCheckChanged(itemData.copy(isSelected = !itemData.isSelected))
            }
        )
    }
}

最后是ItemListLazyColumn

@Composable
fun ItemList() {

    val itemDataState = remember { ItemDataState() }

    LazyColumn {
        items(itemDataState.itemDataList, key = { it.id } ) { item ->
            ItemDisplay(
                itemData = item,
                onCheckChanged = itemDataState::onItemSelected
            )
        }
    }
}

所有这些都是可复制和粘贴的,所以你可以快速运行它。代码应该足够简单,让你很容易地剖析它们,并将它们作为你自己用例的参考。
注意,我们这里使用了一个数据类,它有一个唯一的id属性,我们将它用作LazyColumn'sitemkey参数。
我通常使用唯一标识符实现UI集合组件,以保存UI显示/删除/回收错误项目等潜在的麻烦。

qc6wkl3g

qc6wkl3g2#

记住索引而不是布尔值(isSelected)。

相关问题