导航组件:找不到NavController

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了导航组件:找不到NavController相关的知识,希望对你有一定的参考价值。

我正在使用导航组件在我的应用程序中导航。它在片段内工作正常,但无法在包含实际导航主机的活动中找到导航主机。

我试图在用户点击FAB时打开一个新片段,我将其包含在Main活动的XML中。当我调用findNavController()时,它无法找到控制器。导航主机控制器采用XML布局。我无法理解为什么它找不到它。

主要信息

class MainActivity : AppCompatActivity(), OnActivityComponentRequest {
    override fun getTabLayout(): TabLayout {
        return this.tabLayout
    }

    override fun getFap(): FloatingActionButton {
        return this.floatingActionButton
    }

    private lateinit var tabLayout: TabLayout
    private lateinit var floatingActionButton: FloatingActionButton

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)
        this.tabLayout = tabs
        this.floatingActionButton = fab

        fab.setOnClickListener {

         it.findNavController().navigate(R.id.addNewWorkoutFragment)

        }
    }
}

Activity_main XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        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:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".domain.MainActivity"
        android:animateLayoutChanges="true">

    <com.google.android.material.appbar.AppBarLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

        <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

            <com.google.android.material.tabs.TabItem
                    android:text="Test 1"
                    android:layout_height="match_parent"
                    android:layout_width="match_parent"/>

            <com.google.android.material.tabs.TabItem
                    android:text="Test 2"
                    android:layout_height="match_parent"
                    android:layout_width="match_parent"/>
        </com.google.android.material.tabs.TabLayout>

    </com.google.android.material.appbar.AppBarLayout>

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


    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"/>


    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchorGravity="right|top"
            app:layout_anchor="@+id/bar"
            android:src="@drawable/ic_add_black_24dp"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
答案

尝试在活动的onStart中设置Fab按钮的onClickListener,如onCreate中的活动只是给视图充气并且没有设置NavHostController。因此,如果您在onStart中设置onClickListener活动将按预期工作。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(toolbar)
    this.tabLayout = tabs
    this.floatingActionButton = fab
  }

override fun onStart() {
    super.onStart()
    floatingActionButton.setOnClickListener {
      it.findNavController().navigate(R.id.addNewWorkoutFragment)
    }
  }
另一答案

原来那个持有导航控制器的活动......没有导航组件。

解决方案是手动将NavController设置为活动中包含的每个视图。

val navController = findNavController(R.id.nav_host_fragment)
Navigation.setViewNavController(fab, navController)

现在这可行:

fab.setOnClickListener {

    it.findNavController().navigate(R.id.addNewWorkoutFragment)

}

我仍然不明白为什么它的工作方式如此有效,所以任何解释都会受到欢迎:)

截至目前,Android API根本没有多大意义。

资料来源:Navigate to fragment on FAB click (Navigation Architecture Components)

以上是关于导航组件:找不到NavController的主要内容,如果未能解决你的问题,请参考以下文章

使用 NavController 从片段导航到另一个片段

导航组件 - 模仿Navcontroller图形

IllegalArgumentException:此 NavController 未知导航目的地 xxx

从通知导航到带有 NavController 的片段

如何知道何时调用了`navController.popBackStack()`?

导航组件在 onActivityResult 内导航不起作用