Kotlin - 在运行函数之前等待多个 LiveData 被观察到

Max*_*Max 5 android viewmodel kotlin android-livedata

我正在使用 viewModel 从房间数据库中提取实时数据。我有 2 个从 viewModel 中提取的 LiveData,然后我将运行一个函数从我的服务器中提取数据。在运行将从我的服务器获取信息的函数之前,我需要设置这两个值,因为这些值是帖子正文的一部分。

这是我活动的一部分

var locationSeleted:Long=0L

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView<ActivityBinding>(this,R.layout.activity)

        //This is to get the viewmodel
        val application = requireNotNull(this).application
        val dataSource = Database.getInstance(application).DatabaseDao
        val viewModelFactory = ViewModelFactory(dataSource, application)
        val ViewModel = ViewModelProviders.of(this,viewModelFactory).get(ViewModel::class.java)

        binding.ViewModel = ViewModel
        binding.setLifecycleOwner (this)

        //Get location from livedata
        ViewModel.Location.observe(this, Observer {location ->

            if (location == null){
                //do something
            }
            else{
                locationSeleted = location.locationId
            }

        })

        //listens to the live data of the products value
        ViewModel.Products.observe(this, Observer{products ->
            
            if (products == null){
                //do something
            }
            else{
                myfunction(products)
            }

        })
Run Code Online (Sandbox Code Playgroud)

这是我的视图模型的一部分

class ViewModel(val database: DatabaseDao, application: Application) : AndroidViewModel(application) {


    //This gets the location selected
    var Location: LiveData<LocationSelect> = database.get_location()

    //This line gets the products
    var Products: LiveData<Array<Products>> = database.get_products()


Run Code Online (Sandbox Code Playgroud)

我当前的代码有效,但我可以想象,如果 Location LiveData 延迟,那么 myfunction 将在没有位置的情况下运行,并且 Post 调用将失败。我的问题是如何在从 viewModel 设置位置和产品时调用 myfunction?或者有没有更好的方法来做到这一点。

谢谢

Ten*_*r04 5

您可以使用 MediatorLiveData 以便您只需要观察一件事,并且仅在收到两个项目时才会触发,之后的每次更改都会触发。

在视图模型中:

val locationAndProductsLiveData: LiveData<Pair<LocationSelect, Array<Products>>> = 
    object: MediatorLiveData<Pair<LocationSelect, Array<Products>>>() {
        var location: LocationSelect? = null
        var products: Array<Products>? = null
        init {
            addSource(Location) { location ->
                this.location = location 
                products?.let { value = location to it }
            }
            addSource(Products) { products ->
                this.products = products 
                location?.let { value = it to products }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

在您的活动中:

ViewModel.locationAndProductsLiveData.observe(this) { (location, products) ->
    locationSelected = location.Id
    myFunction(products)
}
Run Code Online (Sandbox Code Playgroud)