持续创作,加速成长!这是我参与「日新计划 6 月更文挑战」的第6天,点击查看活动详情

添加依赖

使用导航组件之前需要添加相关的依赖,在本篇笔记中使用的代码都是用的kotlin,所以这里只添加的kotlin相关的依赖,如下所示:

def nav_version = "2.4.2"
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

如果需要添加其它语言的支持依赖,可以访问这里的地址添加对应的依赖。

导航图

之前我们进行Fragment切换,基本上都容器中有某种酒精含量的酒精溶液是使用FragmentManager配合FrappreciateagmapproachentTranscation自己进行操作的,但是使用导航组件则不是这样,我们需要创建导航图来指定页面(Activity或者Fragment)之间的跳转。

创建导航图

导航图是一种资源文件,其中包含了所有目的地和操作,这个图标会显示应用所有的导航路径,下面是一个简单的导航图的示例.

Android导航组件学习(一)

首次添加导航图资源的时候需要执行如下操作:

  • 需要创建一个导航图资源,如nav_test接口.xml,这里就和普通创建kotlin和java资源文件的方式是一样的,需要注意的就是在最后选择类型的时候选择Navig接口和抽象类的区别ation,这之后就会在当前项目的res目录下添加一个navigation目录,此目录下就有刚才创建的nav_test容器对桌面的压强怎么算.xml这个导appreciate航图资源文件

导航图文件说明

从文件的命名上我们就可以知道,这是一个x容器所能容纳什么叫做容器的容积ml文件,java环境变量配置创建了nav_test.xml资源文件时,AS会自动帮我们打开Navigation Editor,我们可以在这里直观地对导航图进行修改,也可以直接修改其中的xml代码。

添加导航宿主

导航kotlin和java宿主是NavigatAPPion组件的核心部分之一,kotlin什么意思这是一个空的容器,用于在应用中导航时,目的地会在该容器中交换进出。

导航宿主必须实现NavHost接口,导航组件容器英文的默认NavHost实现kotlin和java区别NavHostFragmAPPent负责处理Fragment的目kotlin匿名函数的地交换。

另外需要注意的是:导航组件旨在用于具有一个Activity和多个Fragment容器云目的地的应用。主Activity与导航图相关联。且包含一个负责根据需要交换目的地的NaapplicationvHostFragment。在具有多个Activity的应用中,每个Activity均具有自己的导航图。

下面是在approve我们的代码中的一个Activijava模拟器ty中为了使用导航组件添加的一个Fragment:

        <!--导航容器-->
        <androidx.fragment.app.FragmentContainerView
                android:id="@+id/nav_fragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="@dimen/dp_0"
                android:layout_height="@dimen/dp_0"
                app:layout_constraintTop_toBottomOf="@id/title"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:defaultNavHost="true"
                app:navGraph="@navigation/nav_test"
                />

其实导航容器就是为了处理这个页面的不同的Frament而使用的,这里默认就使用了NavHostFragment,它可以提供不同Fragment目的地的跳转和交互。

需要注意以下内容:

  • name属性指定了我们使用的Fr容器设计agment,这里就使用默认java是什么意思NavHostFragment
  • navGraph指定了当java语言Activity使用的导航图
  • defaultNavHost表示NavHostFragment可以拦截系统返回键。

添加目的地

在上面我们添加了导航容器,下面就可以添加导航目的地了,导航目的地在导航容器中交换和跳转,我们可以首先创建一个Fjava是什么意思ragment作为导航目的地。Fragment非常简单,可以自行创建。

创建完Fragment之后,我们就可以接口回到之前创建的nav_test.xmlkotlin什么意思文件中,在code视图下通过点击New Destinatjavascription来创建一个目的地,在创建的时候我们就可以选择刚才已经创建好的Fragment作为目的地,添加完目的地后,就可以在资源文件中看到这个设置了:

    <fragment
            android:id="@+id/simpleContentFragment"
            android:name="yourPackageName.SimpleContentFragment"
            android:label="@string/simple_content_fragment" />

上面的字段解释如下:

  • fragment: 这个表示的是目的的类型,表示当前的目的地是APPActi接口测试vityFragmenappeartappstore者其它的自定义类型
  • label: 这个字段用于设置目的地的用户可读名称
  • name: 这个字段表Kotlin示的是与该目的地相关联的类的名称
  • id: 表示该目的地的id,它用于在代码中引用该目的地

执行完上面的操作之后,运行代码,就可以在页面中看到我们添加的那个Fragjava语言ment了,也就是上面的Simp容器设计leContentFragment,运行结果如下图所示:

Android导航组件学习(一)

可以看到,这里显示的就是我们定义的SimpleContentFragment,也就是说,我们定义的导航组件是有效果的,我们在FragmentContainerView中指定的是NavHostFragmkotlin是什么ent,显示的是我们在nav_test.xml文件中定义的SimpleContentFragme容器所能容纳什么叫做容器的容积nt

连接到目的地

对于单ActivityFragment的应用程序来说,Fragment才是页面的真正的载体,也就必然存在容器英文从一个Fragment跳转到另一个Fragment的操作,在使用导航组件的时候,我们有两种方式实现这个操作:

  • 使用action标签从一个目的地连接到另一个目的地
  • 创建全局操作,从应用的任意位置跳转到特kotlin是什么定的目java是什么意思的地

使用action标签可以表示从一APP个目的地连接到另一个目的地的操作,但是我们仍然需要编写执行导接口类型航操作的代码,加入我们需要从一个Fragment跳转到另一个Fragment中,我们kotlin语言可以在nav_test.xml文件容器是什么中添加如下的代码:

    <fragment
            android:id="@+id/simpleContentFragment"
            android:name="yourpackagename.SimpleContentFragment"
            android:label="@string/simple_content_fragment"
            tools:layout="@layout/fragment_simple_content">
        <action
                android:id="@+id/action_to_nav_getting_start"
                app:destination="@id/navGettingStartFragment" />
    </fragment>
    <fragment
            android:id="@+id/navGettingStartFragment"
            android:name="yourpackagename.NavGettingStartFragment"
            android:label="@string/nav_fragment_getting_start"
            tools:layout="@layout/fragment_nav_getting_start" />

从上面的文件中就可以看到,我们又定义了一个NavGettingStartFragment,同时定义了一个action操作,这个action表示了我们将会从SimpleContentFragment连接到NavGettingStartFragmentkotlin为什么流行不起来中,其中id表示的接口测试是自身的id,destinatikotlin为什么流行不起来on表示的是要连接到的目的地的id,action操作至少应该包含这两个id。

导航到目的地

上面我们已经说过,nav_test.xml中通过action只能指定连接操作,但是仍然是需要我们添加跳转java语言功能的代码.这里的跳转跳转操作是通过NavController完成的,它是一个在Njava是什么意思avHost中管理应用导航的对象。每个NappearavHost均有自己的Nav容器所能容纳什么叫做容器的容积Controller,不同kotlin语言NavHost中通过下面的方式检索Navkotlin和javaController

  • Fragment中使用Fragment.kotlin语言findNavController()
  • View中使用View.find容器的容积一定比它的体积小NavCkotlin语言ontroller()
  • Activity中使用Activity.findNavController(viewId: Int)

加入我们希望从SimpleContentFragment接口类型导航到NavGettingStartFragment接口是什么,我们便可以做如下的操作:

    findNavController(R.id.nav_fragment).navigate(R.id.action_to_nav_getting_start)

appleActivity中通过finNavController(viewId: Int)来查找对应的NavController,之后调用它的navigate(id)方法即可执行跳转。

Android导航组件学习(一)

但是需要注意的是:如果是使用FragmentContainerView创建的NavHostFragment,或者通过Fragment接口卡Transaction手动容器英文NavHostFragment添加到Activity中时,此时在ActivityonCreate()方法中使用findNavController(R.id.nav_java是什么意思f接口和抽象类的区别ragment)检索NavController将会失败并抛出异常,这个时候应该改为直接从NavHostFrajava怎么读gment中直接检索NavController,如下所示:

//直接检索NavController抛出异常
     Caused by: java.lang.IllegalStateException: Activity XXXActivity@a3b4b50 does not have a NavController set on 2131296826
        at androidx.navigation.Navigation.findNavController(Navigation.kt:50)
        at androidx.navigation.ActivityKt.findNavController(Activity.kt:31)

在如上的情况下,如果接口自动化需要在ActivityonCreate()阶段就使用NavController则应使用如下的方式:

        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_fragment) as NavHostFragment
        navHostFragment.navController.navigate(R.id.action_to_nav_getting_start)

还有一点需要注意的是,如果当前已经处于要导航的目的地了,那容器云么继续使用同样的actionId进行导航则会报错,如下所示:

//在已经进行过一次导航的基础上继续使用同一个actionId继续进行导航出现如下的错误:
Caused by: java.lang.IllegalArgumentException: Navigation action/destination xxx:id/action_to_nav_getting_start cannot be found from the current destination Destination(xxx:id/navGettingStartFragment) label=nav_getting_start_fragment class=xxx.NavGettingStartFragment
        at androidx.navigation.NavController.navigate(NavController.kt:1536)
        at androidx.navigation.NavController.navigate(NavController.kt:1468)