【问题标题】:ViewModel observed every back to fragmentViewModel 观察每个返回片段
【发布时间】:2020-12-17 16:15:21
【问题描述】:

我的 MainActivity 包含 5 个带有 ViewPager 的片段(FragmentA、FragmentB、FragmentC....E)。 FragmentA 具有 viewModel 并观察一个名为“showPopupSuccess”的 MutableLiveData,它在执行任务后设置为 true。

问题是当我去 FragmentC 然后回到 FragmentA。弹出窗口再次显示,因为观察者看起来像“重新激活”。如何摆脱这个?我希望 mutableLiveData 被重置。所以它没有任何价值,也没有显示弹出窗口

如果您想进一步了解,这是该错误的视频 https://www.youtube.com/watch?v=Ay1IIQgOOtk

【问题讨论】:

  • 解决此问题的正确方法是在您转到另一个片段时更新您的 UI 状态。该片段再次显示弹出窗口,因为状态仍然相同。添加更多状态以表示“任务成功但已显示”(或其他),在这种特定状态下,您的 FragmentA 仍然知道它是成功的,但不会调用 showPopup()。因此,当您单击(我认为)显示“配置文件”(底部栏)时,您应该将其传递给您的虚拟机。 VM 应该推送状态以确保如果您返回,现在会再次显示弹出窗口。

标签: android mvvm android-viewmodel


【解决方案1】:

解决问题的最简单方法:使用Event wrapper 第一次观察LiveData,您可以将其内容标记为handled,而不是“重置”它。那么你反复观察就知道它已经被处理过了,可以忽略它。

为了根据指南创建更好的答案,我复制了链接文章中的相关信息:

包装器:

/**
 * Used as a wrapper for data that is exposed via a LiveData that represents an event.
 */
open class Event<out T>(private val content: T) {

    var hasBeenHandled = false
        private set // Allow external read but not write

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * Returns the content, even if it's already been handled.
     */
    fun peekContent(): T = content
}


在 ViewModel 中:

// Instead of Boolean the type of Event could be popup
// parameters or whatever else.
private val _showSuccess = MutableLiveData<Event<Boolean>>()

val showSuccess : LiveData<Event<Boolean>>
    get() = _showSuccess

在片段中:

myViewModel.showSuccess.observe(viewLifecycleOwner, Observer {
    it.getContentIfNotHandled()?.let {
        // This is only executed if the event has never been handled
        showSuccess(...)
    }
})

【讨论】:

  • 当我转到片段 C 并返回片段 A 时,片段 A 是重新创建还是隐藏后重新显示?
  • 这与您的原始问题无关,无法在评论中回答。如果您对 Fragments 有其他问题,请创建一个新问题。您询问了 LiveData 中的事件重复数据删除。我毫不怀疑这个答案会满足您的要求。如果是这样,请接受答案,以便其他人知道已解决的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
相关资源
最近更新 更多