关于android:LiveData,可通过每次返回一个新LiveData的存储库函数从UI刷新?

LiveData which can be refreshed from UI with a repository function that returns a new LiveData each time?

我在存储库类中有以下方法,该方法从本地数据库或网络中以LiveData的形式返回国家列表:

1
2
3
4
5
fun loadCountries(): LiveData<Resource<List<Country>>> {
    return object : NetworkBoundResource<List<Country>, List<CountryResponse>>() {
        ...
    }.asLiveData()
}

在ViewModel中,我有一个LiveData可以保留返回的LiveData:

1
2
3
4
5
6
7
8
9
class CountryViewModel : ViewModel() {

    val countryListResource: LiveData<Resource<List<Country>>> = countryRepository.loadCountries()

    fun refresh() {
        // How to assign new LiveData returned by countryRepository.loadCountries() here?
        // SwitchMap needs other LiveData to be used.
    }
}

用户应该能够刷新数据,这就是我的问题所在。我需要将countryRepository.loadCountries()返回的新LiveData注入到countryListResource中,我不知道该如何实现?

如果我执行countryListResource = countryRepository.loadCountries()(由于它是val,所以无法执行),观察者需要停止观察上一个,而开始观察最新的一个。

如果在countryListResource上使用swichMap,则需要另一个MutableLiveData来触发来自存储库的新调用,如下所示。

还有其他方法可以实现吗?


解决方案非常简单。
首先,在您的存储库类中创建国家列表类型的可变的obj1和不可变的obj2实时数据对象。
Obj2用obj1初始化。然后loadCountry()函数应该只更新obj1。

您的视图模型应使用observeForever()观察obj2。
然后视图模型也确实创建了两个与repo相同的obj,分别是obj3和obj4 resp。在您的活动中观察obj4。 Obj3正在使用observeForever()中的postValue()更新,并依次更新obj4(由obj3初始化)。

希望这对您有所帮助。

示例:

Repository

1
2
3
4
5
6
7
8
9
10
11
// obj1
private val _countryLiveData : MutableLiveData<List<Country>>

// obj2
val countryLiveData : LiveData<List<Country>>
        get() = _countryLiveData

fun loadCountries() {
    val list = fetchCountryList()
    _countryLiveData.postValue(list)
}

ViewModel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// obj3
private val _countryLiveData : MutableLiveData<List<Country>>

// obj4  live data to be observed in activity
val countryLiveData : LiveData<List<Country>>
    get() = _countryLiveData

init {

countryRepository.countryLiveData.observeForever { countryList ->
         this._countryLiveData.postValue(countryList)
   }
}

fun refresh() {
    countryRepository.loadCountries()  
}