My listeners to changes have a lifetime and in order not to keep them in memory, I think I need to add a method, for example, removeItemChangeListener
and call it, for example, in the onClear
method of the view model. As far as I know, the onClear
method is overridden as onCreate
for the activity. Also, it seems to me that i need to convert the listener type to an interface.
MyItemsRepository.kt
interface MyItemsRepository {
val items: List<ItemModel>
fun setFavorite(itemModel: ItemModel, isFavorite: Boolean)
fun addItemChangeListener(listener: () -> Unit)
}
ContentViewModel.kt
class ContentViewModel(
private val repository: MyItemsRepository
) : ViewModel() {
private val _items: MutableLiveData<List<ItemModel>> = MutableLiveData()
val items: LiveData<List<ItemModel>>
get() = _items
var isFavorite: Boolean = false
init {
repository.addItemChangeListener {
getItems()
}
}
fun changeFavoriteState(item: ItemModel, favorite: Boolean) {
repository.setFavorite(item, favorite)
}
fun getItems() {
_items.value = if (isFavorite) {
repository.items.filter { it.isFavorite }
} else {
repository.items
}
}
class Factory : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return ContentViewModel(MyItemsRepositoryImpl.getInstance()) as T
}
}
}
I need your help writing the code. I mentally understand how to do it, but I don't know how to write it. I would be very grateful for a written example with an explanation.
Maybe try calling the method removeItemChangeListener
the same way you're calling setFavorite
, Just call it from the onCleared
method of a ViewModel
class ContentViewModel(
private val repository: MyItemsRepository
) : ViewModel() {
...
override fun onCleared() {
super.onCleared()
repository.removeItemChangeListener()
}
}
And in your repository it would be something like this:
override fun removeItemChangeListener() {
listeners.clear()
}
You cannot really do something like this: listeners.remove(listener)
because how are you going to pass the listener from ViewModel to repository anyway?
Add the removeItemChangeListener
method in the interface MyItemsRepository
interface MyItemsRepository {
...
fun removeItemChangeListener()
}
Again, haven't really tested it, but it should work.
EDIT:
Different approach:
class ContentViewModel(
private val repository: MyItemsRepository
) : ViewModel() {
var listener = {
getItems()
}
init{
repository.addItemChangeListener {
listener
}
}
...
override fun onCleared() {
super.onCleared()
repository.removeItemChangeListener(listener)
}
}
And in your repository it would be something like this:
override fun removeItemChangeListener(listener: () -> Unit) {
listeners.remove(listener)
}
Add the removeItemChangeListener
method in the interface MyItemsRepository
interface MyItemsRepository {
...
fun removeItemChangeListener(listener: () -> Unit)
}
I'm not really sure if this will work. Try it out and let me know.