Home > Blockchain >  Jetpack Compose lazy column all items recomposes when a single item update
Jetpack Compose lazy column all items recomposes when a single item update

Time:12-06

I'm trying to do some list operations and I've run into the issue of all items recomposing when a single item update.

enter image description here

You can update your ViewModel with SnapshotState list as

class MyViewModel : ViewModel() {

    private val initialList = listOf(
        Person(id = 0, name = "Name0"),
        Person(id = 1, name = "Name1"),
        Person(id = 2, name = "Name2"),
        Person(id = 3, name = "Name3"),
        Person(id = 4, name = "Name4"),
        Person(id = 5, name = "Name5"),
        Person(id = 6, name = "Name6"),
    )

    val people = mutableStateListOf<Person>().apply {
        addAll(initialList)
    }

    fun toggleSelection(index: Int) {
        val item = people[index]
        val isSelected = item.isSelected
        people[index] = item.copy(isSelected = !isSelected)
    }
}

ListItem composable

@Composable
private fun ListItem(item: Person, onItemClick: (Int) -> Unit) {
    Column(
        modifier = Modifier.border(3.dp, randomColor())
    ) {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .clickable {
                    onItemClick(item.id)
                }
                .padding(8.dp)
        ) {
            Text("Index: Name ${item.name}", fontSize = 20.sp)
            if (item.isSelected) {
                Icon(
                    modifier = Modifier
                        .align(Alignment.CenterEnd)
                        .background(Color.Red, CircleShape),
                    imageVector = Icons.Default.Check,
                    contentDescription = "Selected",
                    tint = Color.Green,
                )
            }
        }
    }
}

Your list

@Composable
fun ListScreen(people: List<Person>, onItemClick: (Int) -> Unit) {
    LazyColumn(
        verticalArrangement = Arrangement.spacedBy(2.dp),
        modifier = Modifier.fillMaxSize()
    ) {

        items(items = people, key = { it.hashCode() }) {

            ListItem(item = it, onItemClick = onItemClick)
        }
    }
}

The code i use for visually checking recomposition

fun randomColor() = Color(
    Random.nextInt(256),
    Random.nextInt(256),
    Random.nextInt(256),
    alpha = 255
)

CodePudding user response:

list.value = list.value.copy(persons = newList)

You basically assign list to a new value which will force LazyColumn to recompose. Also, if you were to change an item's properties without assigning list a new value You wouldn't see that item updated on the list either. So I don't think you can force recomposition for an item.

  • Related