Populate and emit StateFlow List

8.1k Views Asked by At

I want to use StateFlow. But for now, I don't find any lecture which could help me.

I'm facing an issue : To start, I have a singleton which hold a list of String, I want something "easy" to understand even if it isn't the goal purpose for now. The purpose is to populate and emit the list with strings (it will be a complex object later).

class CustomStateFlow() {
    private val _custom = MutableStateFlow(emptyList<String>())
    val custom: StateFlow<List<String>> = _custom

    fun addString(string: String) {
        val tempList = _custom.value.toMutableList()
        tempList.add(string)
        _custom.value = tempList
}

This seems to work, but I don't like the temp list... without, I can't trigger the "collect" of custom in my fragment.

Is there a way to achieve this without using a tempList ?

Thanks you

3

There are 3 best solutions below

0
On BEST ANSWER

If you don't want to take temporary variable in-order to add new item to mutable list you can use plus (+) operator function. By doing so returns you new list (immutable) with added value that you can use further.

So the pseudo-code becomes something like this: val newList = oldMutableList + newItem

Similarly you can remove item from list like val newList = oldMutableList - itemToRemove

Read more about operator function on kotlin collection here!

0
On

I was looking for a solution too, and I found it in the "Now in Android" app. Here the link to the git https://github.com/android/nowinandroid

You can use the MutableStateFlow.update() function:

fun addString(string: String) {
    _custom.update{it->
        it+string
    } 
}

it in the lambda is the list. The + operator add string to the list.

1
On

There are 3 stages Im doing this within; the repo, the view model and the compose function.

Repository where the data manipulated

    //This object is the list you will edit
private val _easyChatList =  mutableListOf<ChatDescriptionEntity>()
//This object is a wrapper. if you pass it a new object it will call emit
private val _easyChatListHolder = MutableStateFlow(listOf<ChatDescriptionEntity>())
//this object sends out the immutable list
override val easyChatList = _easyChatListHolder.asStateFlow()

//-- add() or remove or sort or shuffle etc --//

   fun sortUpdatedChatLists()
{
    _easyChatList.sort()


    val nl = _easyChatList.toList() // extract a new list to force the emit

    _easyChatListHolder.value = nl


}

viewmodel for your fragment or compose where the list is sent

  var easyChatList: MutableState<List<ChatDescriptionEntity>> = mutableStateOf(listOf())

init {

    repositoryInterface.getChatsList()

    viewModelScope.launch {

        repositoryInterface.easyChatList.collect{
                i -> easyChatList.value = i
        }
    }


}

Lastly in you compose method. any compose that is handed the mutablestate from your viewmodel will react to list changes

val chatList = viewModel.easyChatList.value


ChatListContent(items = chatList, action = navToChat)