当前位置: 首页 > 知识库问答 >
问题:

观察ViewModel LiveData从没有中间转换变量的片段

松灿
2023-03-14

我在我的Android应用程序中遵循MVVM架构。(https://developer.android.com/jetpack/guide)。我所有的存储库函数都返回一个网络边界资源对象。你可以从jetpack指南链接中阅读更多关于这个设计实现的信息,或者从谷歌这里查看示例项目

在这个特殊的问题中,当我在屏幕上下拉时,我试图通过网络重新获取信息。

目前的工作执行情况

片段侦听器(当屏幕下拉时触发)

binding.refresh.setOnRefreshListener {
    profileViewModel.refreshUserProfile()
}

然后在我的ViewModel中,我有一个MutableLiveData,用于更新此函数调用的值

private val _refresh = MutableLiveData<Boolean>()

fun refreshUserProfile() {
    _refresh.value = true
}

刷新时。值更改,它会触发开关映射

val currentUserProfile: LiveData<Resource<UserProfile>> = _refresh.switchMap {
    if (it) {
        repository.getCurrentUserProfile(_username.value.toString())
    } else {
        AbsentLiveData.create()
    }
}

存储库功能


fun getCurrentUserProfile(username: String): LiveData<Resource<UserProfile>> {
    return object : NetworkBoundResource<UserProfile, UserProfile>(AppExecutors.getInstance()) {
        override fun saveCallResult(item: UserProfile) {
            userProfileDao.update(item)
        }
        override fun shouldFetch(data: UserProfile?): Boolean {
            return true
        }
        override fun loadFromDb(): LiveData<UserProfile> {
            return userProfileDao.load(username)
        }
        override fun createCall(): LiveData<ApiResponse<UserProfile>> {
            return networkService.userProfileService.getUserProfileAsync(
                token,
                username
            )
        }
    }.asLiveData()
}

然后回到我的片段,我在这个currentUserProfileViewModel变量上有一个观察者

profileViewModel.currentUserProfile.observe(viewLifecycleOwner, { userProfileResult ->
    when (userProfileResult.status) {...}
})

我想做什么

我想跳过设置刷新的步骤。value=true。而是像这样直接观察存储库功能:

val currentUserProfile: LiveData<Resource<UserProfile>> = 
    repository.getCurrentUserProfile(_username.value.toString())

但是这个实现不会触发片段中的观察者。

问题我不太明白为什么我不能用第二个实现触发observer。我也不确定我最初的实现是最优的还是正确的。如果您熟悉这种设计,我将非常感谢您的反馈。

共有1个答案

东和怡
2023-03-14

我过去也有过类似的问题

  1. 插入/更新的dao实例与观察livedata的dao实例不同
  2. 我的livedata对象被包装在其他一些livedata中

您可以记录该实例

我的猜测是,在您的情况下,这很可能是第二种情况。由于您的livedatauserProfileDao.load被包装在NetworkBoundResource.asLiveData()

为了确认这是问题所在,您可以尝试收听从userProfileDao返回的直接livedata。加载(用户名)。使用在存储库中创建方法

你可以试着往那个方向挖掘更多。

 类似资料:
  • 问题内容: 我想知道是否有什么办法可以在程序运行时观察变量值的变化。当然不使用调试器,我想以 编程方式进行 。例如: 因此,在运行时,如果在我的项目中任何类的任何方法中修改了此value 事件,则应调用该事件。 问题答案: 您需要用一个类替换该类型,该类将在值更改时调用您的侦听器。您可能想忽略未实际更改的值的设置。 例如 您可以使用字节码注入执行此替换,但是更改原始代码非常简单。 一种替代方法是监

  • 问题内容: 给定汽车清单(),我可以这样做: 有没有办法我可以从一个到一个序列? 像没有参数的东西 问题答案: 您可以这样映射到: 请注意,flatMapping可能不会保留源可观察的顺序。如果订单对您很重要,请使用。

  • 问题内容: 我正在尝试将项目设置为表视图,但是setitems方法需要一个可观察的列表,而我的模型中却有一个可观察的集合.FXCollections实用程序类没有给定可观察的集合来创建可观察的列表的方法。类强制转换异常(按预期)。 目前,我正在使用这种代码 而且我有一些问题: 在表中进行编辑是否会按预期更新基础集? 这是这样做的“正确”方法吗 简而言之,我需要样式指南或最佳做法,以便在可观察集和可

  • 问题内容: 如何在Angular中使用多个变量,并在其中之一发生更改时触发回调。 问题答案: 更新 Angular现在提供了两种范围方法$ watchGroup (从1.3开始)和$watchCollection。这些已被@blazemonger和@kargold提及。 这应该独立于类型和值而工作: 在这种情况下,您必须将第三个参数设置为true。 在这种情况下,字符串连接将失败: 在用户单击按钮

  • 我在Java中得到了以下错误消息:“无法从<code>StringProperty</code>转换为<code>ObservableValue 我正在使用TableView,并希望在TableColumn中添加数据。我有三个图表,它们都应该包含类产品的一个属性(名称、数量、价格)。 我在这一行中得到了错误: 相关代码: