稍后在ViewModel中初始化LiveData

时间:2020-05-28 11:16:53

标签: android kotlin android-livedata android-viewmodel

最近选择使用LiveData,在初始化变量时遇到问题。 我有2个活动(我不使用导航,但那不是重点):

  • 一个是列表,其中包含通过API提取的项目
  • 另一个是上一个列表中所选项目的明细活动

问题是我需要能够在创建模式下查阅Detail Activity,即在我的ViewModel中,不得通过Retrofit来检索对象,而必须通过新的实例化来创建对象。

这是目前的做法:

详细活动:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.details)

        val isNew = intent.extras?.getBoolean("new")
        if (isNew) {
            // Trigger lazy property
            viewModel.value
        } else {
            viewModel.getDetails()
        }

        presenter.value.observe(this, Observer { value ->
            value?.let {
                displayDetails(it)
            }
        })
    }

ViewModel

class DetailsPresenter(private val repository: WorkOrderRepository)
    : ViewModel(), LifecycleObserver {

    val value: MutableLiveData<Details> by lazy { MutableLiveData(Details("")) }

    fun getDetails() {
        RetrofitClient.getDetails()
        .onSuccess {
            this.value.value = it
        }

    }

}

此方法的问题是我的displayDetails()方法被调用了两次。 一个用于延迟初始化,另一个用于我正在查看现有项目的情况。

稍后如何在代码中初始化LiveData?

2 个答案:

答案 0 :(得分:2)

基本上,lazy不会创建第二个实例,ViewModel引用也不会重新创建。 因此,我们可以使用Val value: LiveData<Details> = MutableLiveData()代替lazy

您可以在getDetails()块本身中添加init方法,以避免再次调用。

答案 1 :(得分:1)

当然,它将被调用两次,第一次调用是因为您在View中注册了一个观察者,这使得lazy工作并创建了LiveData对象。第二次调用它是因为Retrofit更新了LiveData对象。您是在发出网络请求,它们总是要花一些时间才能完成,直到那时,您的程序在等待请求完成的同时开始执行下一行(在您的情况下是设置观察器)。

如果不考虑value的条件而观察它,则懒惰初始化if-else对象是没有意义的。

我将在ViewModel的init块中进行改造调用并将其缓存在其中。

您可以使用lateinit关键字稍后再初始化对象。

lateinit var myLiveData: LiveData<T>

要检查myLiveData是否已初始化,只需写入if (::myLiveData.isInitialized)