android - 防止在弹出后重新导航,在 onObserve 中?

标签 android mvvm navigation observable android-livedata

我在我的新项目中使用 MVVM + Retrofit + 导航并从存储库调用 retrofit。现在,当我在 fragment-A 中收到带有 liveData 的响应时,我导航到下一个 fragment-B,到目前为止一切看起来都很好。问题从 fragment B 中我想弹出到上一个 fragment 并编辑某些内容的位置开始。

在前面的 fragment ( fragment -A)中,一旦初始化,onObserve 就会被调用并再次导航到 fragment -B!

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

  1. 导航到 fragment B 后设置值(null)
  2. 移除 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/

相关文章:

c# - WPF MVVM : Saving Data automatically

html - Bootstrap - 汉堡包导航不垂直堆叠

c# - 根据 WPF 中的情况自定义菜单

c# - 从 MVVM 读取 ListView 数据

javascript - JQuery 导航集类

jsf-2 - 相当于 page.xml 中的限制、 Action 执行和导航规则(Java EE + JSF 2.0 - 来自 Seam)

android - 如何使用 LibGDx 制作安卓动态壁纸?

java - Google 登录错误 12500 SHA1 双重检查 GoogleSignInAccount account =completedTask.getResult(ApiException.class);

java - 添加使用 java 8 的 .jar 文件后的 Android 编译循环

java - android unicode 到可读字符串