防止在弹出后重新导航,在 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!

我想到了一些有效的解决方案,例如:

  1. setValue(null) 在导航到 fragment-B
  2. 之后
  3. 移除 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)