listkotlinstatesnapshotlazycolumn

How to change the SnapshotStateList in Kotlin Compose? But not just visually but internally


I want to recompose a LazyColumn after I change it's List. I found a solution but it is not working as I expected.

Now the LazyColumn does recompose but on every change the SnapshotStateList use the initial State List instead of the already modified List.

The following is my current code:

class colNames(
val name:String,
val id:String
)

var colparent:List<colNames> = emptyList<colNames>()

//Process filling the List
var tempList: MutableList<colNames>
//Some code
colparent = tempList.toList()

val index = remember { mutableStateof(0) } //ADDED FOR DEBUGGING

val listItems = remember { colparent.toMutableStateList() }                      
                                           
LazyColumn(modifier = Modifier.padding(top = 36.dp)) 
{
    itemsIndexed(
       items = listItems ,
       key = { _, item -> item.id },
    ) { ind, item ->
        Text(
             text = item.name,
             modifier = Modifier
               .clickable(
                   onClick = {
                     colparent = reorderNamesList(colparent, ind, index) 
                     //Above is a test function that changes the item position 
                     //in the list ramdomly by the index
                     colparent.forEachIndexed { id, x -> listItems[id] = x } 
                     //This is where I change the SnapshotStateList
                     //detects the State change thus the LazyColumn refreshes.
                  } 
                )
             )
       }
}

Previous code does refresh but on every onClick instead of working on the new listItems it works on the original States.

I have the following List:

name : index (in the initial State List)
Address Line 1:0
Address Line 2:1
city:2
country:3
geolocation:4
name:5
state:6
use:7
zip code:8

To see the state of the List I added a Log like this on the onClick before the change:

Log.d("Order Change", "${item.name}:$ind:$index")

Then I Click on the [first item:0] repeatedly

Which brings me:

2024-07-22 14:19:43.224 17687-17687 Order Change     com.mastering.houseinventory     D  Address Line 1:0:5
2024-07-22 14:19:50.614 17687-17687 Order Change     com.mastering.houseinventory     D  Address Line 1:0:7
2024-07-22 14:20:05.595 17687-17687 Order Change     com.mastering.houseinventory     D  Address Line 1:0:6

Notice that it always have [Address Line 1] on position [:0] which is the initial State.

I would have expected after each change a new State:

Address Line 1:0:5
name:0:7
use:0:8

This cause the LazyColumn to recompose the view but with different Order than expected by me.

What can I do to really change the List and the LazyColumn to recompose on every change with the new List?


Solution

  • After some time I change the LazyColumn code in a way that inadvertently solve the problem.

    I removed the "key line" as below:

    LazyColumn(modifier = Modifier.padding(top = 36.dp)) 
    {
    itemsIndexed(
       items = listItems ,
       ////////// key = { _, item -> item.id }, REMOVE THIS LINE OF CODE
    ) { ind, item ->
        Text(
             text = item.name,
             modifier = Modifier
               .clickable(
                   onClick = {
                     colparent = reorderNamesList(colparent, ind, index) 
                     //Above is a test function that changes the item position 
                     //in the list ramdomly by the index
                     colparent.forEachIndexed { id, x -> listItems[id] = x } 
                     //This is where I change the SnapshotStateList
                     //detects the State change thus the LazyColumn refreshes.
                  } 
                )
             )
       }
    }
    

    It seems the "key code" makes the SnapshotStateList to be non-Mutable.