如何为侦听器创建方法?
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)
}
我不确定这是否可行。试试看,让我知道。
我对更改的监听器有一个生命周期,为了不让它们保留在内存中,我想我需要添加一个方法,例如 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)
}
我不确定这是否可行。试试看,让我知道。