Android Fragments Android ViewModel MutableLiveData多次更新

js4nwp54  于 12个月前  发布在  Android
关注(0)|答案(3)|浏览(156)

场景

嗨,我有一个带有ViewPager的Activity。在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,也会执行观察块上的代码。

我努力

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

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


但这并不奏效。
帮帮忙,

8yoxcaq7

8yoxcaq71#

如果你想阻止你的观察者的多次调用,你可以把MutableLiveData改为SingleLiveEvent

643ylb08

643ylb082#

它可能会帮助你:

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()扩展函数将其 Package 在OneTimeEvent中:

liveData.postValue(yourObject.toOneTimeEvent())


第二,当你在LiveData上观察时,在传递的值上使用consume { }函数来获得OneTimeEvent的特性。你将确保consume { }的块只会被执行一次。

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


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

9nvpjoqh

9nvpjoqh3#

如果你想防止多次调用你的观察者,只需在观察者之前使用 distinctUntilChanged

mainViewModel.isResponseSuccessful.distinctUntilChanged().observe(this, Observer { it ->
        if(it) {
            //do Something
        }else{
            Toast.makeText(activity, "Error in Sending Request", Toast.LENGTH_SHORT).show()
        }
    })

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

字符串

相关问题