异常:视图未设置navController

10

当我在活动的片段标签中托管片段时,在该片段中使用navController = Navigation.findNavController(view)时,应用程序会因错误而崩溃: 视图没有设置navController。

这是nav_graph:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/mainFragment">

    <fragment
        android:id="@+id/mainFragment"
        android:name="studio.apptick.mouj.view.fragments.MainFragment"
        tools:layout="@layout/fragment_main"
        android:label="fragment_main" >
        <action
            android:id="@+id/action_mainFragment_to_playlistActivityFragment"
            app:destination="@id/playlistActivityFragment" />
        <action
            android:id="@+id/action_mainFragment_to_searchActivity"
            app:destination="@id/searchActivity" />
    </fragment>
    <activity
        android:id="@+id/searchActivity"
        android:name="studio.apptick.mouj.view.activity.SearchActivity"
        android:label="activity_search"
        tools:layout="@layout/activity_search" />
</navigation>

这是在Activity中的Fragment标签:

        android:id="@+id/nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/view_player"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph">
    </fragment>
9个回答

9

我遇到了相同的问题,直到我意识到我们必须像这样在onPostCreate函数中设置navControol

@Override
public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
    super.onPostCreate(savedInstanceState, persistentState);

    BottomNavigationView navigationView = findViewById(R.id.nav_view);


    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
            R.id.navigation_home, R.id.navigation_memories, R.id.navigation_account)
            .build();
    NavController navController = Navigation.findNavController(this, R.id.main_fragment);
    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    NavigationUI.setupWithNavController(navigationView, navController);
}

你如何处理NavController和后退栈。例如,你已经选择了第二个导航项,其中包含5个片段。你现在在第4个片段并且想要退出当前片段并回到第二个导航项的第1个或第2个片段。 - Dens

9

如果你想在activity中使用navController,你可以通过以下方式找到它:

navController = Navigation.findNavController(Activity, R.id.nav_host_fragment)

或者在一个片段中。
navController = NavHostFragment.findNavController(Fragment)

或者

navController = Navigation.findNavController(View)

2
在适配器中怎么样? - mafortis

6

我今天遇到了类似的错误。

java.lang.IllegalStateException: Activity com.example.roomtutorial.MainActivity@2a8d7bb 没有在2131231116上设置NavController

当指向 setupActionBarWithNavController(findNavController(R.id.mainFragment)) 时,我收到了这个错误。

因此问题出在XML文件中。

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"

等我遇到问题时,通过将<androidx.fragment.app.FragmentContainerView更改为<fragment来解决。

设计该选项的人真的搞砸了。


1
这也是我的崩溃原因。这个问题的一般解决方法是什么?我实际上想使用FragmentContainerView - Taslim Oseni

2
您可以使用Kotlin扩展函数导航到目标。
findNavController().navigate(R.id.action_homeFragment_to_destinationFragment)

此外,请确保按照Android建议使用FragmentContainerView替换片段标记。
<androidx.fragment.app.FragmentContainerView
   android:id="@+id/my_nav_host_fragment"
   android:layout_width="match_parent"
   android:name="androidx.navigation.fragment.NavHostFragment"
   app:defaultNavHost="true"
   app:navGraph="@navigation/nav_graph"
   android:layout_height="match_parent"/>

1
我在我的项目中使用这个解决方案。
navController = (supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController

navController.addOnDestinationChangedListener { controller, destination, arguments ->
                when(destination.id){
                    R.id.genre->{ materialToolbar.title = getString(R.string.app_name) }
                    R.id.search->{ materialToolbar.title = getString(R.string.search) }
                    R.id.favorites->{ materialToolbar.title = getString(R.string.favorites) }

                }
            }

1
在片段的情况下,在视图创建后启动navController。
 //    ....
lateinit var navController: NavController
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    navController = Navigation.findNavController(view)
    //...
}

0
如果您通过以下方式获取navController:
NavController navController = Navigation.findNavController(Activity, R.id.nav_host_fragment);

解决方案1

通过以下方法获取navController

NavHostFragment navHostFragment =
                (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();

带有布局:

<androidx.fragment.app.FragmentContainerView
   android:id="@+id/nav_host_fragment"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:name="androidx.navigation.fragment.NavHostFragment"
   app:defaultNavHost="true"
   app:navGraph="@navigation/nav_graph"/>

它完全符合文档

解决方案2

只需将<androidx.fragment.app.FragmentContainerView更改为<fragment

这对我有效,但我没有找到任何相关的文档。

希望能有所帮助!


0

我曾经遇到过同样的问题,后来发现问题出在我的活动类上,它没有像使用基本活动和片段创建活动时那样进行配置。尝试创建基本活动并查看创建的活动类是否与你最初遇到问题的类相似。


1
目前你的回答写得不是很清晰。请编辑并添加更多细节,以便其他人能够理解这个问题的答案。你可以在帮助中心找到更多关于如何撰写好答案的信息。 - Vikram Parimi

0

您可以在导航宿主片段视图上简单地使用post方法:

    nav_host_fragment.post {
        findNavController(R.id.nav_host_fragment).addOnDestinationChangedListener { _, des, _ ->
            when(des.id){
                //your conditions here
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接