我在我的新项目中使用 MVVM + Retrofit + 导航并从存储库调用 retrofit。现在,当我在 fragment-A 中收到带有 liveData 的响应时,我导航到下一个 fragment-B,到目前为止一切看起来都很好。问题从 fragment B 中我想弹出到上一个 fragment 并编辑某些内容的位置开始。
在前面的 fragment ( fragment -A)中,一旦初始化,onObserve 就会被调用并再次导航到 fragment -B!
我想到了一些有效的解决方案,例如:
- 导航到 fragment B 后设置值(null)
- 移除 onCreateView 中的 observe 并在从 repository 调用 retrofit 时观察它(此解决方案会产生其他问题)
等等
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// fetch data from server
viewModel.articles.observe(viewLifecycleOwner) {
//if it was success
findNavController().navigate(R.id.fragment_a_to_fragment_b)
}
}
最佳答案
在只应处理一次实时数据负载的情况下,您应该使用包装负载的事件类:
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
}
在您的 View 模型中,您应该像这样设置事件:
fun loadArticles() {
val data = // load data from repository
articles.value = Event(data) // Trigger the event by setting a new Event as a new value
}
然后像这样观察:
viewModel.articles.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { // Only proceed if the event has never been handled
findNavController().navigate(R.id.fragment_a_to_fragment_b)
}
})
有关详细信息,请参阅 LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)
关于android - 防止在弹出后重新导航,在 onObserve 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57591001/