构建单Activity的APP——Navigation(下)

415 阅读2分钟

这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

本文继续介绍几个Navigation的常用功能。

动画

动画可以很简单的添加在action中,可以对一条导航的起点和终点页面进出NavHost进行描述。在XML可以像这样写:

slide_enter_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%p" android:toXDelta="0"
        android:duration="@android:integer/config_mediumAnimTime"/>
</set>

nav.xml

<action
            android:id="@+id/action_fragment_home_to_test1Fragment"
            app:destination="@id/test1Fragment"
            app:enterAnim="@anim/slide_enter_right"
            app:exitAnim="@anim/slide_exit_left"
            app:popEnterAnim="@anim/slide_pop_enter_left"
            app:popExitAnim="@anim/slide_pop_exit_right" />

这样我们就实现了从左侧退出,从右侧进入的页面导航动画。我们可以用AS在nav.xml的Design界面点击这条action,侧边的Attribute中还能直接配置你写好的跳转动效。

image.png

在kt代码中我们还能这样写:

val option: NavOptions = NavOptions.Builder()
        .setEnterAnim(ctx.resources.getIdentifier("slide_enter_right", "anim", defPackage))
        .setExitAnim(...)
        .setPopEnterAnim(...)
        .setPopExitAnim(...).build()
navController.navigate([导航路线],option)

NavController提供的navigate()函数,能让我们很轻松地实现对不同类型目的地的导航,还能添加动画效果。这种代码构建的方式虽然没有XML可视化那样直观,但是在应对个别比较困难的场景中确实不可或缺的,例如组件化时,组件间的跳转用xml根本没法实现。

嵌套图

嵌套图是指NavGraph的导航可以让你从导航至另一个NavGraph的默认首页去,这就像是一张导航图嵌套着另一张导航图。像下面这样写,就可以从跳转到另一个nav了。

nav.xml

<fragment
        android:id="@+id/test1Fragment"
        android:name="com.xx.xx.xx.Test1Fragment"
        android:label="ShowcaseFragment" >
        <action
            android:id="@+id/action_fragment1_to_nav_new"
            app:destination="@id/nav_new"/>
    </fragment>
<include app:graph="@navigation/nav_new" />

嵌套图不仅仅在于缩减了NavGraph的行数,它还以graph为单位模块化了不同的fragment。众所周知,Jetpack为Activity和Fragment提供了一个叫做ViewModel的东西,能帮忙管理他们的数据。Fragment之前要想通信的话,利用承载他们的Activity的ViewModel来管理通信数据是很好的一个做法。然而我们的App一般会有不同模块的很多个页面,这样就算是用Activity的多个ViewModel,也是不太好方便的。不过Navigation的graph是可以挂载ViewModel的,这样就优雅地解决了问题。

全局操作

一般的导航是在fragment中添加的action,,而全局操作是在NavGraph中添加一个action,代码如下: nav.xml

<navigation>
        <action
            android:id="@+id/action_global_loginFragment"
            app:destination="@id/loginFragment"/>
</navigation>

在给NavGraph中的任一Fragment加了这个后,任何此NavGraph都可以跳转至这一Fragment了,这样很方便,但不建议常用,一般适合给DialogFragment用。

深链接

深链接是一个比全局操作更开放的功能,它可以很轻松的在同一个APP的bundle之间跳转。它甚至能从APP外部跳转到持有深链接的页面,不过从外部APP跳转至深链接页面不在本系列文章的探讨范围内,有兴趣的同学可以去下面的官方文档学习一下。