android - ViewModel 观察每个返回片段
问题描述
我有 MainActivity,它包含 5 个片段(FragmentA、FragmentB、FragmentC....E)和 ViewPager。FragmentA 具有 viewModel 并观察一个名为“showPopupSuccess”的 MutableLiveData,它在执行任务后设置为 true。
问题是当我去 FragmentC 然后回到 FragmentA。弹出窗口再次显示,因为观察者看起来像“重新激活”。如何摆脱这个?我希望 mutableLiveData 被重置。所以它没有任何价值,也没有显示弹出窗口
如果您想进一步了解,这是该错误的视频 https://www.youtube.com/watch?v=Ay1IIQgOOtk
解决方案
解决问题的最简单方法:使用Event
包装器
而不是“重置” 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
}
在视图模型中:
// 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(...)
}
})
推荐阅读
- python - 如何通过散景图中的选择更改来替换面板的一部分?
- c++ - 如何使用 swig 将 const 字符串参数从 perl 传递到 c++
- json - 批量更新 PostgreSQL 中的 JSON 字段
- flutter - 带有列和行的颤振座椅视图
- c# - Jenkins 构建失败并出现错误“未安装文件扩展名 '.tif' 的 IFilter”但在本地工作
- objective-c - 在目标c的tableview中加载时重复选择单元格
- python - 未安装来自自定义通道的 Conda 依赖项
- ios - 您可以从 PDF 数据创建 UIImage 吗?
- python - 无法在 python 中访问 args 值
- javascript - 在特定(空间)位置播放视频