方向更改时NavController崩溃

时间:2019-08-16 15:07:34

标签: android kotlin android-jetpack android-jetpack-navigation

我不确定我在做什么错。设置简单,单个活动,其中片段受内部底部栏的控制,到目前为止效果很好。起始片段内部有一个按钮,应可以导航到另一个片段。

以下是片段类中按钮的onclicklistener:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    add_step_fab.setOnClickListener {
        Navigation.findNavController(view).navigate(R.id.fragmentAtoB)
    }
}

这是我在navigation.xml中的动作:

<fragment android:id="@+id/navigation_main" android:name="com.test.test.fragments.AFragment"
          android:label="Fragment A" tools:layout="@layout/fragment_a">
    <action android:id="@+id/fragmentAtoB"
            app:destination="@id/fragmentB" app:enterAnim="@anim/nav_default_enter_anim"
            app:exitAnim="@anim/nav_default_exit_anim" app:popEnterAnim="@anim/nav_default_pop_enter_anim"
            app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
</fragment>

导航正常,但是我得到了标准

java.lang.IllegalArgumentException: navigation destination com.test.test:id/fragmentAtoB is unknown to this NavController
旋转屏幕,分屏显示应用或有时看似随机后,单击按钮时出现

错误。看起来与配置更改有关?

编辑: 我也尝试使用

val clickListener: View.OnClickListener = Navigation.createNavigateOnClickListener(R.id.fragmentAtoB)
    add_step_fab.setOnClickListener(clickListener)

具有与上述相同的问题。

检查我是否实际上在同一片段中,如某些为具有相同异常(但出于不相关原因)的用户所建议的那样,例如:

if (controller.currentDestination?.id == R.id.navigation_main) {
            controller.navigate(R.id.fragmentAtoB)
        }

也没有帮助。

3 个答案:

答案 0 :(得分:6)

在几个月的应用程序正常运行后,我最近也遇到了这种情况。我最初是将导航添加到使用“ MainActivity”类的应用程序中,然后再通过菜单启动其他活动(这与让Navigation组件在单个Activity的片段之间导航相反)。

因此,应用的组织方式使得MainActivity为“枢纽”,菜单选项中的选项会导致其他活动启动,而当用户从菜单中返回时,它们又回到了MainActivity-所以是一个纯粹的“枢纽( MainActivity)和语音(其他5个活动)”模型。

在MainActivity.onCreate()中称为setupNavigation()方法,其最初看起来像这样:

private void setupNavigation() {
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    drawerLayout = findViewById(R.id.drawer_layout);

    // This class implements the listener interface for the NavigationView, handler is below.
    NavigationView navigationView = findViewById(R.id.nav_view);
    navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);
    NavigationUI.setupWithNavController(navigationView, navController);

    // MainActivity implements the listener for navigation events
    navigationView.setNavigationItemSelectedListener(this);

}

正如我提到的那样,即使直到最近才进行了配置更改,此方法也能正常工作。即使只是将MainActivity上的配置从纵向更改为横向也会导致异常:

ComponentInfo{com.reddragon.intouch/com.reddragon.intouch.ui.MainActivity}: java.lang.IllegalStateException: You must call setGraph() before calling getGraph()

我发现我必须添加这一行:

navController.setGraph(R.navigation.nav_host);

在Naviation.findNavController()调用之后,然后它处理配置更改就很好了。

答案 1 :(得分:0)

更改配置后,片段或活动会暂时超出范围,然后执行onResume()覆盖。如果您有在onCreate()或onViewCreated()中初始化的任何内容,则这些变量可能已超出范围,现在为空值。因此,我通常有一个称为RestoreAll()的方法,该方法负责实例化代码使用的所有对象,并且我从onResume()调用此方法,以便每次进行配置更改时,所有本地对象都会重新存储。 -实例化。

答案 2 :(得分:0)

更改配置后,导航控制器后堆栈有问题。尝试这个: https://stackoverflow.com/a/59987336/5433148