当我在 LiveData 观察器中使用 navController 时,Android 导航组件图停止正常工作

Ale*_*kov 5 navigation android android-livedata android-architecture-navigation

我在我的演示应用程序中使用了 android 导航组件。我有一个非常简单的案例。一个活动,两个片段,A 和 B。我已经按照 Google 的示例应用程序设置了导航控件。当我尝试使用简单的 onClickListener 从 A 打开片段 B 时,如下所示:

val button.setOnClickListener {
       val action = AFragmentDirections.openFragmentB()
       findNavController().navigate(action)
    }
Run Code Online (Sandbox Code Playgroud)

一切正常。B 片段打开,通过点击后退按钮它会弹出。但是当我尝试从 LiveData 观察者使用它时,如下所示:

viewModel.openFragmentB.observe(viewLifecycleOwner, Observer {
        val action = AFragmentDirections.openFragmentB()
        findNavController().navigate(action)
    })
Run Code Online (Sandbox Code Playgroud)

片段 B 打开,但通过点击后退按钮应用程序崩溃,错误导航目标 com.myapp:id/open_fragmetn_b 是此 NavController 未知的。

为什么会发生这种情况以及如何将导航组件与 LiveData 一起使用?

Ale*_*lex 6

发生此崩溃是因为当您单击后退按钮时,您的视图模型 openFragmentB 观察者再次收到通知,并且它正在尝试使用操作 openFragmentB 导航到 Fragment B,但此时 NavController 当前目的地仍然是 Fragment B,而 Fragment B 没有有动作 openFragmentB。

对此有多种解决方案,简单的一种是在您的观察者中添加检查该值是否为空,最后将 openFragmentB 值设置为空:

if(it!=null) {
    val action = AFragmentDirections.openFragmentB()
    findNavController().navigate(action)
    viewModel.openFragmentB.value=null
}
Run Code Online (Sandbox Code Playgroud)

但为了更好的方法,您可以阅读有关 SingleLIveEvent 的信息:https ://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150