![Android Jetpack应用指南](https://wfqqreader-1252317822.image.myqcloud.com/cover/927/32517927/b_32517927.jpg)
3.3 使用Navigation
接下来,我们一起来学习如何使用Navigation。
3.3.1 创建Navigation Graph
新建一个Android项目后,依次选中res文件夹→New→Android Resource File,新建一个Navigation Graph文件。如图3-1所示,将File name设置为“nav_graph”,Resource type设置为“Navigation”。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_46_1.jpg?sign=1739282582-ZMxwXq9CtTmnhFI9dhQ3UKwG1teL9Ovb-0-4c627c2f57d7d60786b372617c16cfec)
图3-1
单击“OK”按钮,Navigation Graph就创建完成了。
所生成的nav_graph.xml文件与普通布局文件类似,也有Design和Text面板。在此,我们能在Destinations面板中,看见“No NavHostFragments found”的提示,如图3-2所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_47_1.jpg?sign=1739282582-0dkIOO1WgEi6Gsl7k03gkE5MrBx5dFWj-0-c7d701e592fccc966b5aac400c81ea4a)
图3-2
需要注意的是,Navigation的使用需要依赖于相关支持库,因此Android Studio可能会询问你,是否自动帮你添加相关依赖,单击OK即可,如图3-3所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_47_2.jpg?sign=1739282582-Whq0lm8L4RR4A0e75EmfxwRfkdmmYKx8-0-a16da18a73ffcea96d857a8a4db42a89)
图3-3
当然,你也可以在build.gradle文件中手动添加依赖,示例如下。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_48_1.jpg?sign=1739282582-uDvHSiZVZq5I1VtKhH3TQcuqbLTPRM8W-0-bc3225441a879545c015452339493152)
3.3.2 添加NavHostFragment
NavHostFragment是一个特殊的Fragment,我们需要将其添加到Activity的布局文件中,作为其他Fragment的容器。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_48_2.jpg?sign=1739282582-jrQKY4mMTFhzCsYT857oD5T7y9aXedG2-0-75942ea16bca350d946070d26211ffaa)
请注意,下面这一行代码在告诉系统,这是一个特殊的Fragment。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_49_1.jpg?sign=1739282582-DBXgQx2upCXg3QZJk1mTfCSjC98Qidh0-0-1f46ef2f157c8bed4a3a10a00442c2a1)
将app:defaultNavHost属性设置为true,则该Fragment会自动处理系统返回键。即当用户按下手机的返回按钮时,系统能自动将当前所展示的Fragment退出。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_49_2.jpg?sign=1739282582-HQQl1YgpthocRv4DN68vCI85zTbFWjAP-0-2d06408ddcc725e30b8d45507f7782c6)
app:navGraph属性用于设置该Fragment对应的导航图。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_49_3.jpg?sign=1739282582-bO8oV8TlCOAm0bjxHbkHOFBv0VIYocUv-0-deceee1fd54e45f2485973643fb9df94)
添加NavHostFragment之后,再回到导航图上。此时,在Destinations面板中可以看见我们刚才设置的NavHostFragment,如图3-4所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_49_4.jpg?sign=1739282582-Nw1cPzuxGd0wbZP0H9aH6r5BZVzqyDkk-0-275bc708a730c3cf6aeeec856f181476)
图3-4
3.3.3 创建destination
依次单击加号按钮、“Create new destination”按钮,创建一个destination,如图3-5所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_50_1.jpg?sign=1739282582-pre8hFfOdmg5weeuqG9WdLA3qfbBcNeh-0-d15707775f24fd18a5d12d63d89b370e)
图3-5
destination是“目的地”的意思,代表着你想去的页面。它可以是Fragment或Activity,但最常见的是Fragment,因为Navigation组件的作用是方便开发者在一个Activity中管理多个Fragment。在此,我们通过destination创建一个名为MainFragment的Fragment,如图3-6所示。
接着,再次单击加号按钮,此时出现了我们刚才创建的MainFragment对应的布局文件fragment_main,如图3-7所示。单击该文件。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_51_1.jpg?sign=1739282582-AwH6mV2MXHAO2WvXmfrnHqY5o2lBRlqS-0-c87d256774c9b26d64f2e377c7ad282f)
图3-6
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_51_2.jpg?sign=1739282582-DmxZJvs5mTMB1sUZe9jP2FYT1CCYVjqd-0-229143e7821c3d0bc5b04c5ca6e005a5)
图3-7
面板中出现了一个mainFragment,如图3-8所示。“Start”表示该MainFragment是起始Fragment,即NavHostFragment容器首先展示的Fragment。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_52_1.jpg?sign=1739282582-OqR66QtgHV5oZ6UYr9146mCMt3zbr9DG-0-b4cddf3629afe0afb51d66868fc94747)
图3-8
单击图3-8左下方的Text面板,查看布局文件的内容。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_52_2.jpg?sign=1739282582-9iT861oPFAqznhig6exOoGXUwF2l2zxL-0-29233050b17b72abc58d4b1a95913dc0)
可以看到,在navigation标签下有一个startDestination属性,该属性指定起始destination为mainFragment。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_53_1.jpg?sign=1739282582-KWTiALee1haSQXevNXpDFWXfy7p9KqIU-0-dba651258b04604a6187ffb1581b673f)
运行程序,可以看到一个空白的Fragment,即destination所指定的mainFragment,如图3-9所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_53_2.jpg?sign=1739282582-vPNcZ4mRqzpqDEWgsYDZz8Yiw4frAXss-0-f3eeb30cb6d8f6fc0b624a84b1ec4916)
图3-9
3.3.4 完成Fragment页面切换
接下来看看Navigation如何帮助我们实现Fragment页面的切换。
与创建MainFragment的方式类似,先创建一个SecondFragment。如图3-10所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_53_3.jpg?sign=1739282582-zCdU8XVNHgUX8jPCAMuHQ0FaCrEi9aSk-0-7fcdc5b12aa1190a04d1e5b9e3878d73)
图3-10
单击mainFragment,用鼠标选中其右侧的圆圈,并拖拽至右边的secondFragment,松开鼠标,如图3-11所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_54_1.jpg?sign=1739282582-5ca4q7NNVnn3W0bjK33n0rypv2ewvoIN-0-0472e499ef0dc2b49f9fdea6d096221d)
图3-11
此时出现一个从mainFragment指向secondFragment的箭头,如图3-12所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_54_2.jpg?sign=1739282582-YuYdT32QYWkslE2UVxK2q03nVWqUVtOX-0-a16e002d69c1b288fe74e70bd5583884)
图3-12
切换到Text面板,查看布局文件。可以看到多了一个<action/>标签,app:destination属性表示它的目的地是secondFragment。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_55_1.jpg?sign=1739282582-3sHyT8hEqUnIiIwHbLqAX20uNau7VcfR-0-85f5858c94c6e456bee17878329c3ce9)
3.3.5 使用NavControIIer完成导航
经过以上步骤后,我们还需要通过NavController对象,在代码中完成具体的页面跳转工作。
在MainFragment的布局文件中添加一个Button。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_56_1.jpg?sign=1739282582-1MRtka7y8e04oIcnPyKalPaJbmxyH4u3-0-e776129073967bc5f8a5cc7879357c22)
接着打开MainFragment,响应这个按钮的单击事件,完成具体的页面切换。需要注意的是,有两种方式可以完成页面的跳转,代码如下所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_57_1.jpg?sign=1739282582-FpsOGSSLmIKUzEqfBcH1LkSHAlA23GXI-0-9b605d7ec150587aae9dafb0fe3115a1)
运行应用程序可以看到Fragment完成了切换,但切换没有动画效果,显得很生硬。Navigation组件考虑到了这一点,通过Android Studio,可以便捷地为页面切换添加动画。
3.3.6 添加页面切换动画效果
首先,在res/anim文件夹下加入常见的动画文件,如图3-13所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_58_1.jpg?sign=1739282582-RQno8PgFeSisV0LbwiL8xpdYzxRsqj8y-0-2aba5208a086b32b09cdfbbef2298b6d)
图3-13
接着,打开导航文件的Design面板,选中箭头,并在右边的Animations面板中为其设置动画文件,如图3-14所示。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_58_2.jpg?sign=1739282582-QiWuxbtuzLpTV15nJzO44VWZLZqYOD6Q-0-484c32450b7fd45ccb03b1058ac7c82e)
图3-14
切换到Text面板,查看布局文件。可以看到它在<action/>标签中自动为我们添加了动画的相关代码。实际上,我们也可以直接在此编写代码,Design面板只是使用了可视化的方式以方便操作。
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_58_3.jpg?sign=1739282582-TixeYxWwgT1wWbtT7K8NFmoBLIw3vrWy-0-857d2aa3ea00737a058f7f9a6568dbc1)
![](https://epubservercos.yuewen.com/BC5419/17545851006441506/epubprivate/OEBPS/Images/39055_59_1.jpg?sign=1739282582-xqpPqKHD534S6GO4wel5oyhQzEDjFu4O-0-35e40cf0aa8f4421373d7e43d8b4cd7a)
当然,我们还可以通过NavOptions对象在Java或Kotlin代码中,以代码的方式为Fragment添加页面切换动画,但导航图是比较方便和直观的方式。读者若有兴趣可以自己去尝试,这里就不做过多的介绍了。
运行应用程序,此时切换页面便可以看到动画效果。