Jetpack Navigation Component初探

1,063 阅读4分钟

在这篇博客中,我们将讨论JetpackNavigation Component。假设你已经掌握了Android的基本知识,并且渴望精通Android

什么是 JetPack?

Jetpack是在Google I/O 2018上推出的一套UI组件库,用于帮助开发人员遵循最佳实践,减少样板代码,并编写能够在Android不同版本和设备之间一致工作的代码,以便开发人员能够只专注于写他们关心的代码。

不使用Navigation component

  • 应用程序中的导航任务是手动创建的
  • 没有创建/编辑应用程序路由导航流的标准实践
  • 没有标准的可视化工具来理解应用程序路由流程
  • 没有一致的方法将Activity/Fragment管理到本机应用程序中

使用Navigation component

  • 现在,我们有了标准的API,以及还有IDE中的可视化工具,用以帮助使整个开发过程更加清晰、简单和一致
  • 我们可以使用设计工具来创建路由并定义导航路径

先决条件

导航组件需要Android Studio 3.3或更高版本,并且依赖于Java 8语言特性。

简单介绍

不同屏幕和应用程序中,路由导航是用户体验的核心部分。一些原则为跨应用程序的一致和直观的用户体验设定了一个基准。Navigation component被设计为默认实现这些原则,确保用户在不同应用程序之间,可以有相同的启发式和模式的导航体验。

Navigation是一个用于在Android应用程序中不同页面之间跳转导航的框架,它提供了一致的API,无论目的页面是以ActivityFragment还是其他组件的形式实现的。

Navigation Component由三个部分组成:

  1. Navigation Graph(XML resource): 这个一个包含所有导航页面的文件。它包含应用中所有的ActivitiesFragmentsDialogs,以及用户在应用中可能经过的所有路径。
  2. NavHostFragment(Layout XML view): 这是一个布局中的特殊组件,它用于显示不同页面的路径
  3. NavController (Kotlin/Java object): 这是一个Navigation控制器,当你在不同页面跳转时,它可以用来控制跳转及获取当前位置。

如何使用

步骤一: 在build.gradle中添加依赖

dependencies {
    def nav_version = “2.3.2"

    // Java依赖
    implementation “androidx.navigation:navigation-fragment:$nav_version"
    implementation “androidx.navigation:navigation-ui:$nav_version"

    // Kotlin依赖
    implementation “androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation “androidx.navigation:navigation-ui-ktx:$nav_version"

    // Feature 模块依赖
    implementation “androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

    // 测试模块
    androidTestImplementation “androidx.navigation:navigation-testing:$nav_version"

}

步骤二: 向Activity中添加NavHost

  1. 这是一个Activity的布局,它包含全局导航,一个底部按钮和一个工具栏
  2. android:name="androidx.navigation.fragment.NavHostFragment" app:defaultNavHost="true"将系统的后退按钮连接到NavHostFragment
  3. app:navGraph="@navigation/app_navigation"用于将NavHostFragmentNavigation Graph联系起来,Navigation Graph用于管理所有路由导航。

步骤三: 创建nav_graph文件(Navigation Graph)

它用于将所有页面路由作为子元素添加到一个文件中。注意,请确保所有子元素都分配了唯一的id。

IDE路由提供的路由编辑器

Navigation Editor

自动生成的源码

自动生成的源码

这里使用了四个参数:

  1. android:id: 路由唯一id,跟之前在XML中为其它组件设置id类似
  2. android:name: 路由使用的类名
  3. android:label: 路由名称
  4. tools:layout: 布局文件的id

我们使用startDestination来定义第一个视图位置

我们再来看看action中使用的参数

  1. android:id: action的id
  2. app:destination: 目标页面的id,将当前action跟页面联系起来
  3. app:popUpTo: 如果应用程序已经从页面A导航到页面B,然后从页面B导航到页面C,那么这是为了向后导航。如果要将页面A转到页面C,可以将页面A的id设置到这里。后台导航组件将会自动管理堆栈和生命周期。
  4. popUpToInclusive=true: 表示返回到popUpTo指定的页面后,会清除的栈顶的页面。
  5. 我们还可以定义一些导航动画,我们可以在res/anim文件夹中定义好动画
<fragment
    android:id="@+id/loginFragment"
    android:name="com.android.samples.LoginFragment"
    android:label="fragment_login"
    tools:layout="@layout/fragment_login" >
    <action
        android:id="@+id/action_loginFragment_to_forgotPasswordFragment"
        app:destination="@id/forgotPasswordFragment"
        app:popUpTo="@+id/signinMainFragment"
        app:popUpToInclusive="true"
        app:enterAnim="@anim/slide_in_right"
        app:exitAnim="@anim/slide_out_left"
        app:popEnterAnim="@anim/slide_in_left"
        app:popExitAnim="@anim/slide_out_right"/>
    <action
        android:id="@+id/action_loginFragment_to_tnCFragment"
        app:destination="@id/tnCFragment" />
</fragment>

我们可以定义动画使用下面的属性:

  • app:enterAnim="@anim/slide_in_right"
  • app:exitAnim="@anim/slide_out_left"
  • app:popEnterAnim="@anim/slide_in_left"
  • app:popExitAnim="@anim/slide_out_right"

跳转页面(NavController)

NavController非常强大,因为当您调用像navigate()popBackStack()这样的方法时,它会将这些命令转化为框架兼容的方法。例如,当你调用navigate()时,NavController会内部调用startActivity()

跳转页面使用NavController完成的,这是一个管理NavHost中的应用导航的对象。每个NavHost都有自己对应的NavController。你可以使用以下方法之一来获取一个NavController:

Kotlin:

Java:

Navigation component推荐使用Safe Args这个Gradle插件确保类型安全

我们可以获取一个NavController对象,并通过navigate来跳转

val directions: NavDirections = LoginFragmentDirections.actionLoginFragmentToForgotPasswordFragment()
Navigation.findNavController(view).navigate(directions)

嵌套路由

我们可以将一些路由进行嵌套,以重用一些组件。我们可以使用include来进行设置

<include app:graph="@navigation/profile_nav_graph" />

使用NavigationUI跳转

我们可以在页面共用的如顶部导航栏通过NavigationUI来进行页面跳转