如何通过存储库(数据库/网络)中的LiveData在Android中使用ViewModel?

时间:2018-07-25 21:11:54

标签: android kotlin viewmodel android-architecture-components android-livedata

我有需要显示一些数据的片段/活动。 数据来自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

但是这个例子非常具体。据我了解,我有:

    我需要在开始时使用setId()从VIEW设置
  1. repoId-> 活动/片段

  2. 然后我可以使用retry()刷新视图模型的LiveData中的数据,该方法仅将repoId重置为相同的值

    1. repo,贡献-每次使用设置repoId时,实际可观察​​的LiveData都会通过存储库向Web API发出请求 Transofrmations.switchMap()

所以:在“活动”中,我需要:

  1. viewModel.repo.observe(),viewModel.contributions.observe()

  2. viewModel.setId()-获取初始数据加载

  3. 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
    }
}

这种方法是解决此问题的正确方法吗?还是应该以其他方式实现它。

0 个答案:

没有答案