防止在弹出后重新导航,在 onObserve 中?
preventing from re-navigating after pop, in onObserve?
我在我的新项目中使用 MVVM + Retrofit + 导航并从存储库调用 retrofit。现在,当我在 fragment-A 中收到带有 liveData 的响应时,我导航到下一个 fragment-B,到目前为止一切看起来都很好。问题从 fragment-B 中我想弹出到上一个 fragment 并编辑一些东西的地方开始。
之前的fragment(fragment-A)一初始化就调用onObserve,再次导航到fragment-B!
我想到了一些有效的解决方案,例如:
- setValue(null) 在导航到 fragment-B
之后
- 移除 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)
}
}
在只处理一次实时数据负载的情况下,您应该使用包装负载的事件class:
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)
}
})
有关详细信息,请参阅 LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)
我在我的新项目中使用 MVVM + Retrofit + 导航并从存储库调用 retrofit。现在,当我在 fragment-A 中收到带有 liveData 的响应时,我导航到下一个 fragment-B,到目前为止一切看起来都很好。问题从 fragment-B 中我想弹出到上一个 fragment 并编辑一些东西的地方开始。
之前的fragment(fragment-A)一初始化就调用onObserve,再次导航到fragment-B!
我想到了一些有效的解决方案,例如:
- setValue(null) 在导航到 fragment-B
- 移除 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)
}
}
在只处理一次实时数据负载的情况下,您应该使用包装负载的事件class:
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)
}
})
有关详细信息,请参阅 LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)