Android ViewModel MutableLiveData更新多次

问题描述

场景

嗨, 我有一个带有ViewPager的活动。在ViewPagerAdapter中,我创建具有不同数据的同一片段的实例。 在每个实例中,我都会初始化一个ViewModel

val dataViewModelFactory = this.activity?.let { DataViewModelFactory(it) }
mainViewModel = ViewModelProviders.of(this,dataViewModelFactory).get(MainViewModel::class.java)

在我的片段中,当我调用API时观察到了两个MutableLiveData

mainViewModel.isResponseSuccessful.observe(this,Observer { it ->

        if(it) {
            //do Something
        }else{
            Toast.makeText(activity,"Error in Sending Request",Toast.LENGTH_SHORT).show()
        }


    })

    mainViewModel.isLoading.observe(this,Observer {
        if (it) {
            println("show progress")
        } else {
            println("dismiss progress")
        }
    })

在每个片段中,在按钮上单击“我加载另一个片段”。以及如果需要调用和API来获取数据。

问题

代码在我的片段中多次进入了观察块。当我从一个片段返回到上一个片段时,即使没有调用任何API,也会执行observe块上的代码。

我尝试过的事情

我尝试在ViewModel初始化中使用活动实例

mainViewModel = ViewModelProviders.of(activity,dataViewModelFactory).get(MainViewModel::class.java)

但这没用。

请帮助

解决方法

如果您想阻止观察者的多次呼叫,您可以将MutableLiveData更改为SingleLiveEvent。阅读this

,

它可能会帮助您:

import java.util.concurrent.atomic.AtomicBoolean

class OneTimeEvent<T>(
    private val value: T
) {

    private val isConsumed = AtomicBoolean(false)

    private fun getValue(): T? =
        if (isConsumed.compareAndSet(false,true)) value
        else null

    fun consume(block: (T) -> Unit): T? =
        getValue()?.also(block)
}

fun <T> T.toOneTimeEvent() =
    OneTimeEvent(this)

首先,当您想在LiveData上发布值时,请使用toOneTimeEvent()扩展功能将其包装在OneTimeEvent中:

liveData.postValue(yourObject.toOneTimeEvent())

第二,当您观察LiveData时,请对传递的值使用consume { }函数来获得OneTimeEvent的功能。您将确保consume { }块仅执行一次。

viewModel.liveData.observe(this,Observer {
            it.consume { yourObject ->
                // TODO: do whatever with 'yourObject'
            }
        })

在这种情况下,当片段恢复时,您的代码块将不会再次执行。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...