Флажок в Jetpack Compose не обновляется со значением состояния

Я создаю список данных для многократного выбора, а также хочу добавить функциональность, добавив опцию «Выбрать все», чтобы выбрать/отменить выбор всех элементов одновременно.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я проверяю конкретный элемент, он проверяется/снимается, и значение состояния сохраняется там в этой составной области функции, но когда я выбираю весь элемент списка и обновляю значение в списке, это не отражается на " Выбрать все» и наоборот.

Я делюсь здесь своим кодом для созданной мной составной функции.

  1. Компонуемый для флажка
      @Composable
private fun CheckBox(
        modifier: Modifier = Modifier,
        isChecked: Boolean = false,
        checkedColor: Color = MaterialTheme.colors.primary,
        checkMarkColor: Color = Color.White,
        unCheckedColor: Color = outerSpaceTransparent50,
        size: Dp = 24.dp,
        onCheckChanged: OnCheckChangedListener = {}
) {
    Surface(
            color = Color.Transparent,
            modifier = Modifier.padding(10.dp)
    ) {
        Surface(color = if (isChecked) checkedColor else Color.Transparent,
                modifier = modifier
                        .noRippleClickable {
                            onCheckChanged(!isChecked)
                        }
                        .size(size)
                        .border(width = 2.dp, color = if (isChecked) checkedColor else unCheckedColor, shape = MaterialTheme.shapes.small), shape = MaterialTheme.shapes.small) {


            AnimatedVisibility(
                    visible = isChecked,
                    enter = fadeIn(),
                    exit = fadeOut()
            ) {
                Icon(
                        imageVector = Icons.Default.Check,
                        contentDescription = null,
                        modifier = Modifier
                                .size(size)
                                .padding(4.dp),
                        tint = checkMarkColor
                )
            }
        }
    }


}
  1. Компонуемый для TitleText
      @Composable
fun TitleText(
        modifier: Modifier = Modifier,
        title: String,
        color: Color = outerSpace,
        fontSize: TextUnit = 16.sp,
        fontWeight: FontWeight = FontWeight.Normal,
        overflow: TextOverflow = TextOverflow.Clip,
        maxLines: Int = Int.MAX_VALUE,
        textAlign: TextAlign = TextAlign.Start
) {
    Text(
            modifier = modifier,
            textAlign = textAlign,
            text = title,
            overflow = overflow,
            maxLines = maxLines,
            style = MaterialTheme.typography.h2
                    .copy(
                            color = color,
                            fontSize = fontSize,
                            fontWeight = fontWeight
                    )
    )
}
  1. Компонуемый для флажка с заголовком
      @Composable
fun CheckBoxTitle(
        modifier: Modifier = Modifier,
        isChecked: Boolean = false,
        title: String, maxLines: Int = 1,
        overflow: TextOverflow = TextOverflow.Ellipsis,
        onCheckChanged: OnCheckChangedListener = {}
) {

    val checkedState = remember {
        mutableStateOf(isChecked)
    }

    Surface(color = Color.White, modifier = modifier
            .fillMaxWidth()
            .noRippleClickable {
                checkedState.value = !checkedState.value
                onCheckChanged(checkedState.value)
            }) {
        Row(modifier = Modifier.padding(horizontal = 20.dp, vertical = 3.dp), horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically) {
            CheckBox(isChecked = checkedState.value, onCheckChanged = { value ->
                checkedState.value = value
                onCheckChanged(value)
            })
            TitleText(title = title,
                    color = if (checkedState.value) MaterialTheme.colors.primary else outerSpace,
                    overflow = overflow, fontWeight = if (checkedState.value) FontWeight.SemiBold else FontWeight.Normal, maxLines = maxLines)

        }
    }
}

И вот я тестирую в режиме предварительного просмотра

      private data class CheckBoxTest(val text: String, var isSelected: Boolean = false, val id: String = UUID.randomUUID().toString())

@Preview(showBackground = true)
@Composable
private fun CheckBoxTitlePreview() {

    val dataList = SnapshotStateList<CheckBoxTest>().apply {
        add(CheckBoxTest("Management"))
        add(CheckBoxTest("Development"))
        add(CheckBoxTest("Finance"))
        add(CheckBoxTest("QA Team"))
    }

    val allTeamSelected = snapshotFlow { dataList.all { it.isSelected } }.collectAsState(initial = dataList.all { it.isSelected })

    AppTheme {

        Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
            CheckBoxTitle(
                    title = "Select All",
                    isChecked = allTeamSelected.value,
                    onCheckChanged = { checked ->
                        val updatedItems = dataList.toList()
                        updatedItems.forEach { it.isSelected = checked }
                        dataList.apply {
                            clear()
                            addAll(updatedItems)
                        }
                    }
            )

            dataList.forEach { data ->

                CheckBoxTitle(
                        title = data.text,
                        isChecked = data.isSelected,
                        onCheckChanged = { checked ->
                            data.isSelected = checked
                            val indexOfData = dataList.indexOfFirst { it.id == data.id }
                            if (indexOfData >= 0) {
                                dataList.removeAt(indexOfData)
                                dataList.add(indexOfData, data)
                            }
                        }
                )
            }
        }
    }
}

0 ответов

Другие вопросы по тегам