【问题标题】:Android MVVM - How to make LiveData emits the data it has (forcing to trigger the observer)Android MVVM - 如何让 LiveData 发出它拥有的数据(强制触发观察者)
【发布时间】:2018-12-06 23:12:32
【问题描述】:

我有这个从网络获取列表的ViewModel,我用数据填充RecyclerViewMyAvailabilityRepository 返回一个MutableLiveData,这就是我使用Transformations.switchMap 的原因):

class MyAvailabilityViewModel : ViewModel() {
    private val getListsParams = MutableLiveData<String>()
    private val getListsObservable = Transformations.switchMap(getListsParams) { 
        organizationId -> MyAvailabilityRepository.getSectionedLists(organizationId) 
    }

    fun getListsObservable() : LiveData<Resource<MutableList<SectionedAvailabilityList>>> {
        return getListsObservable
    }

    fun fetchLists(organizationId: String, forceRefresh: Boolean = false) {
        if (getListsParams.value == null || forceRefresh) {
            getListsParams.value = organizationId
        }
    }
}

片段的onActivityCreated:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    ...
    viewModel.getListsObservable().observe(this, Observer { // populate RecyclerView })
    viewModel.fetchLists(organizationId)
}

由于getListParams.value第一次为null,它会设置getListsParams.value = organizationId并触发switchMap并调用repository从网络获取列表。

当我想强制刷新(通过pull-to-refresh)并再次调用网络时,我可以使用forceRefresh = true

override fun onRefresh() {
    viewModel.fetchLists(organizationId, forceRefresh = true)
}

它将设置organizationId 的值并触发随后调用网络的转换。

但是,我有一个场景是我从 RecyclerView 的适配器中清除数据。如果在那之后,用户单击一个按钮,我想再次触发观察者,以便我使用 getListsObservable 已经获取的数据重新填充适配器。我不想在这个上调用 forceRefresh,因为我确定我已经有了数据,我只想再次触发观察者,以便我的 UI 使用现有数据进行更新。由于此时getListParams.value 不为空,所以当我稍后调用fetchLists(organizationId) 时不会发生任何事情。

知道如何使用我当前的设置实现这一目标吗?

【问题讨论】:

    标签: android android-architecture-components android-mvvm android-livedata


    【解决方案1】:

    是的,洪端给出的答案是完美的。 我只是在这里扩展这个答案,

    更好的做法是使用扩展功能。

    我的扩展功能是这样的,

    fun <T> MutableLiveData<T>.forceRefresh() {
        this.value = this.value
    }
    

    调用函数如下所示,

    mutableLiveDataObject.forceRefresh()
    

    编码愉快!!

    【讨论】:

      【解决方案2】:

      再次尝试removeObservers()observe()

      viewModel.getListsObservable().removeObservers(this)
      viewModel.getListsObservable().observe(this, Observer { // populate RecyclerView })
      

      因为:

      如果 LiveData 已经有数据集,则将其交付给观察者。

      请参阅docs

      或者您可以将getListsObservable() 更改为返回MutableLiveData,然后手动调用setValue

      fun loadCurrentData() {
          getListsObservable.value = getListsObservable.value
      }
      

      【讨论】:

        【解决方案3】:

        我确实通过这种方法强制刷新 -

        if (mainViewModel.mutable != null && mainViewModel.mutable.getValue()) {
            mainViewModel.mutable.setValue(mainViewModel.mutable.getValue());
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多