如何在网格/列表中仅选择 3 个元素(jetpack compose)?

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

我有一个包含两列和 6 个元素的网格,但我需要用户仅选择 3 个元素

在第一个@Composable中我这样放置值:

    LazyVerticalGrid(
        columns = GridCells.Fixed(2),
    ) {
        items(list.values.size) {
            InterestsItems(
                value = list.values[it].text,
            )
        }
    }

第二个 @Composable(InterestsItems) 是一个里面有图像的盒子。我这样设置值:

var isSelected by remember { mutableStateOf(false) }
Box(modifier = Modifier.noRippleClickable { isSelected = !isSelected })

结果是我选择了所有元素,不是我想要的。

kotlin android-jetpack-compose android-jetpack
3个回答
1
投票

您可以创建一个数据类来保存任何项目的选定标志

data class InterestsItem(val text: String, val isSelected: Boolean = false)

一个 ViewModel,保留所选项目的项目和索引,并具有在所选和未选择之间切换的功能

class InterestsViewModel : ViewModel() {

    val interestItems = mutableStateListOf<InterestsItem>()
        .apply {
            repeat(6) {
                add(InterestsItem(text = "Item$it"))
            }
        }

    private val selectedItems = mutableListOf<Int>()

    fun toggleSelection(index: Int) {

        val item = interestItems[index]
        val isSelected = item.isSelected

        if (isSelected) {
            interestItems[index] = item.copy(isSelected = false)
            selectedItems.remove(index)
        } else if (selectedItems.size < 3) {
            interestItems[index] = item.copy(isSelected = true)
            selectedItems.add(index)
        }
    }
}

MutableStateListOf
当我们更改项目时会触发重组

@Composable
private fun SelectItemsFromGridSample(interestsViewModel: InterestsViewModel) {
    LazyVerticalGrid(
        columns = GridCells.Fixed(2),
        contentPadding = PaddingValues(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp),
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        itemsIndexed(interestsViewModel.interestItems) { index, item ->
            InterestsItemCard(interestsItem = item) {
                interestsViewModel.toggleSelection(index)
            }
        }
    }
}

还有一些带有回调的可组合项,用于传递该项目被单击

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun InterestsItemCard(interestsItem: InterestsItem, onClick: () -> Unit) {

    ElevatedCard(
        modifier = Modifier.size(100.dp),
        onClick = onClick
    ) {
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text(text = interestsItem.text, fontSize = 30.sp)
            if (interestsItem.isSelected) {
                Icon(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Green, CircleShape),
                    imageVector = Icons.Default.Check,
                    tint = Color.White,
                    contentDescription = null
                )
            }

        }
    }
}

结果


1
投票

您显然对所有项目使用了通用的

isSelected
变量。如果您使用循环来渲染项目,请将变量声明移至循环内。

获取Android 开发者官方网站上的基本编程代码实验室,了解基础知识。通用编程的坚实基础是学习任何特定编程范例/领域的基础。一定要先学习 Compose Pathway,现已更名为 Jetpack Compose Course,。在这种情况下,您需要创建一个表示所选项目的列表或一个哈希映射,它基本上是一个列表,其中每个元素都是一对两个对象。当列表/地图的大小达到 3 时,在单击时处理事件,以防止进一步选择。这取决于您想要做什么,并且应该根据您的项目进行定制。


0
投票

isSelected
变量放入 items 块中。

示例;

val list = remember { mutableStateOf(listOf("0","1","2","3","4","5") )}
LazyVerticalGrid(
    columns = GridCells.Fixed(2),
) {
    items(list.value.size){
        var isSelected by remember { mutableStateOf(false) }
        Text(
            modifier = Modifier.clickable{
                isSelected = !isSelected
            },
            text = list.value[it],
            color = if (isSelected) Color.Red else Color.Black
        )
    }
}

结果;

© www.soinside.com 2019 - 2024. All rights reserved.