我有需要显示一些数据的片段/活动。 数据来自Web API(或可以来自DB)。 我有Repository类,可将此数据作为LiveData向Web API或DB发出请求。
现在,我需要使用LiveData实现ViewModel,并考虑如何正确执行此操作。我尝试类似于以下示例: https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoViewModel.kt
但是这个例子非常具体。据我了解,我有:
repoId-> 活动/片段
然后我可以使用retry()刷新视图模型的LiveData中的数据,该方法仅将repoId重置为相同的值
所以:在“活动”中,我需要:
viewModel.repo.observe(),viewModel.contributions.observe()
viewModel.setId()-获取初始数据加载
viewModel.retry()-每次我想刷新VIEW中的数据
现在在我的活动中,我需要在导航抽屉中显示名字/姓氏。 1.我需要在Activity创建时加载此数据 2.每次打开抽屉或在“活动重启”时(从后台),我都需要刷新此数据。 3.我有UserProfileRepository.getUserProfile()->返回LiveData 这是我的问题!对Web api的此请求不需要任何ID,因为它仅根据标头中的当前身份验证令牌获取用户个人资料(使用拦截器将其传递给HTTP请求标头)
因此,我没有任何repoId或userId(在我的情况下)将其设置为MutableLiveData,然后使用Transformations.switchMap在视图模型上设置其他属性。
我试图直接通过以下方式返回LiveData:
fun getUserProfile() : LiveData<UserProfile> {
return repository.getUserProfile()
}
但是这里是刷新View的问题,因为将来对getUserProfile()的调用只会返回新的Observable LiveData,而不是通知以前的LiveData观察者。
我认为我可以在ViewModel中使用一些MediatorLiveData和本地LiveData属性,但这似乎有些复杂。
因此,我想到了这种方法(使用类型为refresher
的伪造LiveData<Int>
私有财产)。每当我想刷新userProfile(或强制执行存储库以发出Web api请求,返回新的Transformations.switchMap(
>并据我所知放置此 new时,它都会触发LiveData<T
)块执行数据(在ViewModel属性userProfile动态数据中)。这样,每次我调用refresh()方法时,活动的Observer都会收到实际的Web api数据通知。
class UserProfileViewModel
@Inject constructor(private val userProfileRepo: UserProfileRepository) : ViewModel() {
private val refresher : MutableLiveData<Int> = MutableLiveData()
val userProfile : LiveData<Resource<UserProfile>> = Transformations.switchMap(refresher) { refreshCount ->
userProfileRepo.getUserProfile()
}
fun refresh() {
refresher.value = (refresher.value ?: 0) + 1
}
}
这种方法是解决此问题的正确方法吗?还是应该以其他方式实现它。