现在我开始第一次使用LiveData。首先,我将所有代码放入包括要在服务器中开始搜索的代码在内的viewModel中。 我这样使用LiveData:
onViewCreated()片段
viewModel.changeNotifierContacts.observe(this, androidx.lifecycle.Observer { value -> value?.let {
recyclerViewAdapter.setData(value)
} })
这按预期工作。现在,我按照MVVM模式添加一个存储库层。 (为此,我将联系人搜索功能移至了存储库类) 首先,我实现了ViewModel和存储库之间的连接,如下所示:
ViewModel代码:
fun getContacts(): MutableLiveData<ContactGroup> {
return contactSearchRepository.changeNotifierContacts;
}
fun search(newSearchInput: String) {
contactSearchRepository.searchInRepository(newSearchInput)
}
现在,我读到这篇文章,告诉我们不要像这样使用LiveData:https://developer.android.com/topic/libraries/architecture/livedata#merge_livedata
此页面上的示例:
class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
private fun getPostalCode(address: String): LiveData<String> {
// DON'T DO THIS
return repository.getPostCode(address)
}
}
相反,我们应该使用这样的东西:
var changeNotifierContacts : LiveData<ContactGroup> = Transformations.switchMap(searchInput) {
address -> contactSearchRepository.getPostCode(address) }
问题:
感谢您的回应和建议!
答案 0 :(得分:1)
我是否正确理解本文,还是可以使用第一个实现?
我认为您做到了,但是我相信您已经扩展了这个概念。
如果您希望用户输入搜索来获得答案,则应该像他们说的那样做:
class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
private val addressInput = MutableLiveData<String>()
val postalCode: LiveData<String> = Transformations.switchMap(addressInput) {
address -> repository.getPostCode(address) }
fun setInput(address: String) {
addressInput.value = address
}
}
但是,如果要加载默认列表,则应像在第一个示例中那样进行操作:
val getContact = contactSearchRepository.changeNotifierContacts
在这种情况下,您将必须遵守 getContact 和 postalCode 。
在viewModel的构造函数中,我正在创建存储库对象的一个实例,该实例开始观察服务器数据并获取初始数据。 (例如,我正在获取所有朋友的列表)。如果使用第一个实现,我将获得这些初始数据。如果我正在使用Transformations.switchMap实现,则不会获得此初始数据。我首先必须在这里开始搜索以获取更新的数据。这不是我想要的,我还需要不进行搜索就显示“我的朋友”列表。
您可以使用默认搜索开始片段/活动,例如:
MyViewModel.setInput("Friends")
这样,您无需观察两个对象,因为 postalCode 将提供所有答案。
这里还有其他方法可以使用吗?也许LiveData不是将ViewModel与存储库连接的最佳解决方案?
我认为实时数据是您的答案。学习曲线完成后,处理起来就变得更容易了!
希望对您有帮助!