如何为侦听器创建方法?

How do I create a method for listeners?

我对更改的监听器有一个生命周期,为了不让它们保留在内存中,我想我需要添加一个方法,例如 removeItemChangeListener 并调用它,例如,在 onClear 视图模型的方法。据我所知,onClear 方法被 activity 覆盖为 onCreate。另外,在我看来,我需要将侦听器类型转换为接口。

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
        }
    }
}

我需要你帮助编写代码。我心里明白怎么做,但我不知道怎么写。如果能提供一个带有解释的书面示例,我将不胜感激。

它看起来就像您的 addItemChangeListener 函数,只是它应该调用 remove 而不是 add。不确定您不确定概念的哪一部分。将其定义为接口是可选的。接口可能有助于更好地传达听众的目的,但不会改变功能。如果这样做,您可能希望将其定义为 fun interface,因为如果可以使用 lambda 表达式来表示接口,接口会更有趣。

总而言之,如果您对协同程序持开放态度,那么您的存储库将更容易公开 Flow。那么如果ViewModel订阅了Flow,超出作用域就会自动取消订阅。

也许可以尝试以与调用 setFavorite 相同的方式调用方法 removeItemChangeListener,只需从 ViewModel

onCleared 方法调用它
class ContentViewModel(
    private val repository: MyItemsRepository
) : ViewModel() {

    ...

    override fun onCleared() {
        super.onCleared()
        repository.removeItemChangeListener()
    }

}

在您的存储库中,它将是这样的:

override fun removeItemChangeListener() {
    listeners.clear()
}

你真的不能做这样的事情:listeners.remove(listener) 因为无论如何你要如何将侦听器从 ViewModel 传递到存储库?

在界面中添加removeItemChangeListener方法MyItemsRepository

interface MyItemsRepository {
    
    ...

    fun removeItemChangeListener()
}

同样,还没有真正测试过,但应该可以。

编辑:

不同的方法:

class ContentViewModel(
    private val repository: MyItemsRepository
) : ViewModel() {

    var listener = {
        getItems()
    }

    init{
        repository.addItemChangeListener {
            listener
        }
    }

    ...

    override fun onCleared() {
        super.onCleared()
        repository.removeItemChangeListener(listener)
    }

}

在您的存储库中,它将是这样的:

override fun removeItemChangeListener(listener: () -> Unit) {
    listeners.remove(listener)
}

在界面中添加removeItemChangeListener方法MyItemsRepository

interface MyItemsRepository {
    
    ...

    fun removeItemChangeListener(listener: () -> Unit)
}

我不确定这是否可行。试试看,让我知道。