5

I have a list which is stored inside a Viewmodel via Stateflow.

class FirstSettingViewModel : ViewModel() {

     private val _mRoomList = MutableStateFlow<List<InitRoom>>(mutableListOf())
     val mRoomList: StateFlow<List<InitRoom>> = _mRoomList
    
     ...

I observe the flow via collectAsState(). The LazyColumn consists of Boxes which can be clicked.

val roomList = mViewModel.mRoomList.collectAsState()

Dialog {

    ...

    LazyColumn(...) {

        items(roomList.value, key = { room -> room.room_seq}) { room ->
          
           Box(Modifier.clickable {
              **mViewModel.selectItem(room)**
           }) {...}
       }
    }
}

When a click event occurs, the viewModel changes the 'isSelected' value via a copied list like this.

fun selectItem(room: InitRoom) = viewModelScope.launch(Dispatchers.IO) {
    try {
        val cpy = mutableListOf<InitRoom>()
        mRoomList.value.forEach {
            cpy.add(it.copy())
        }
        cpy.forEach {
            it.isSelected = it.room_seq == room.room_seq
        }
        _mRoomList.emit(cpy)
    } catch (e: Exception) {
        ErrorController.showError(e)
    }
}

When in an xml based view and a ListAdapter, this code will work well, but in the above compose code, it doesn't seem to recompose the LazyColumn at all. What can I do to re-compose the LazyColumn?

z.g.y
  • 5,512
  • 4
  • 10
  • 36
March3April4
  • 2,131
  • 1
  • 18
  • 37

1 Answers1

2

Use a SnapshotStateList instead of an ordinary List

change this,

private val _mRoomList = MutableStateFlow<List<InitRoom>>(mutableListOf())
val mRoomList: StateFlow<List<InitRoom>> = _mRoomList

to this

private val _mRoomList = MutableStateFlow<SnapshotStateList<InitRoom>>(mutableStateListOf())
val mRoomList: StateFlow<SnapshotStateList<InitRoom>> = _mRoomList
z.g.y
  • 5,512
  • 4
  • 10
  • 36
  • It works, but I really don't get what's going on. My logic makes one item's isSelected state to true, and others to false. I thought it will only recompose two lazyColumn items, but it seems that all the visible items inside the lazy column is recomposed. Is this a normal case? – March3April4 Nov 07 '22 at 08:37
  • 1
    If you are using at least Dolphin, you can check the `re-composition` count from the Layout Inspector. – z.g.y Nov 07 '22 at 08:41
  • I added a log inside the items lambda to print the key of the item when it's being called. Isn't this the recompose? – March3April4 Nov 07 '22 at 08:55