>我在我的新项目中使用 MVVM + 改造 + 导航,并从存储库调用改造。现在,当我使用 liveData 在片段 A 中收到响应时,我导航到下一个片段 B,到目前为止一切看起来都不错。问题从片段 B 中我想弹出到上一个片段并编辑某些内容的位置开始。
在之前的片段(片段-A(中,一旦初始化,就会调用onObservation并再次导航到片段-B!
我想到了一些有效的解决方案,例如:
- setValue(null( 在导航到片段 B
后 - 删除onCreateView中的观察,并在从存储库调用改造时观察它(此解决方案会产生其他问题(
等。
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
}
在视图模型中,应按如下方式设置事件:
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)
}
})
有关详细信息,请参阅带有 SnackBar、导航和其他事件的 LiveData(SingleLiveEvent 案例(