I need to get an Observer event when the item is added to the List of LiveData. But as far as I understand the event receives only when I replace the old list with a new one. For example when I do the next:
list.value = mutableListOf(IssuePost(UserEntity(name, email, photoUrl), issueEntity))
Observer gets event. But when I just add item to value, Observer is silent. Could you please give me advice on how I can implement what I need?
You usually create an Observer object in a UI controller, such as an activity or fragment. Attach the Observer object to the LiveData object using the observe() method. The observe() method takes a LifecycleOwner object. This subscribes the Observer object to the LiveData object so that it is notified of changes.
Initialize, Update, Observe LiveData LiveData is a wrapper on an object which can be observed from any UI component via a getter method.
This function is deprecated. This extension method is not required when using Kotlin 1.4.
StateFlow and LiveData have similarities. Both are observable data holder classes, and both follow a similar pattern when used in your app architecture. The StateFlow and LiveData do behave differently: StateFlow requires an initial state to be passed into the constructor, while LiveData does not.
Internally, LiveData keeps track of each change as a version number (simple counter stored as an int). Calling setValue() increments this version and updates any observers with the new data (only if the observer's version number is less than the LiveData's version).
It appears the only way to start this process is by calling setValue() or postValue(). The side-effect is if the LiveData's underlying data structure has changed (such as adding an element to a Collection), nothing will happen to communicate this to the observers.
Thus, you will have to call setValue() after adding an item to your list. I have provided two ways you could approach this below.
Option 1
Keep the list outside of the LiveData and update with the reference any time the list contents change.
private val mIssuePosts = ArrayList<IssuePost>() private val mIssuePostLiveData = MutableLiveData<List<IssuePost>>() fun addIssuePost(issuePost: IssuePost) { mIssuePosts.add(issuePost) mIssuePostLiveData.value = mIssuePosts }
Option 2
Keep track of the list via the LiveData and update the LiveData with its own value whenever the list contents change.
private val mIssuePostLiveData = MutableLiveData<MutableList<IssuePost>>() init { mIssuePostLiveData.value = ArrayList() } fun addIssuePost(issuePost: IssuePost) { mIssuePostLiveData.value?.add(issuePost) mIssuePostLiveData.value = mIssuePostLiveData.value }
Either of these solutions should help you from having to create a new list every time you modify the current list just to notify the observers.
UPDATE:
I've been using similar techniques for a while now as Gnzlt has mentioned in his answer to use a Kotlin extension function to assign the LiveData to itself to simplify the code. This is essentially Option 2 automated :) I would recommend doing that.
I use a Kotlin Extension Function
to make it easier:
fun <T> MutableLiveData<T>.notifyObserver() { this.value = this.value }
Then use it in any MutableLiveData
like this:
fun addIssuePost(issuePost: IssuePost) { mIssuePostLiveData.value?.add(issuePost) mIssuePostLiveData.notifyObserver() }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With