Home > Net >  Using stateflow for mutableList in Android
Using stateflow for mutableList in Android

Time:05-03

Working on a project where we need to have a list of items in a view model. The type is a custom data class.

Until now, I have used a MutableLiveData to store the state of the list. The list will be updated when a user scans an item on an RFID reader that we have connected to the device. When scanned, an item will be fetched from a server and the list will be updated accordingly.

I want to try and move on to using a StateFlow instead, but I'm running into an issue here.

When a new item is scanned, I'm updating the mutable list with the add command and later on updating the corresponding item in the list. This does not trigger the LiveData or StateFlow observers/collectors - but with LiveData I could assign the list to itself after I'm done with updating it. (_listOfItems.value = _listOfItems.value) as this would notify observers.

This does not work with StateFlow however, since it only trigger when the reference changes (which it doesn't since it's the same list, just with new/changed items in it).

I'm aware that there are probably some issues with using a mutable list and coroutines to update the same list, since it might collide if trying to update the list at the same time, or something like that.

So, generally the question is: what's the best approach when having a list in a view model and having the UI update whenever the content of the list changes?

CodePudding user response:

It would be impossible to use a MutableList in a StateFlow and make it update because StateFlow always does an equals comparison with the previous value, and since the previous value is an instance of the same list, they will always be considered equal.

You could make this work with SharedFlow, which does not compare values with the previous.

It is however very error prone to use mutable classes with a SharedFlow/StateFlow (or even LiveData) in general because the data could be getting read from and written to from multiple different places. Very hard to manage.

One solution is to create a copy of the list every time you send it to the flow:

myMutableStateFlow.value = myMutableList.toList()

If you want code that's even easier to manage, possibly at the expense of performance, don't use mutable Lists at all. Use read-only Lists. You could put it in a var property, or just modify the value of your StateFlow directly.

myMutableStateFlow.value  = someNewItems
// where myMutableStateFlow's type is a List, not MutableList
  • Related