经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Jetpack系列:应用内导航的正确使用方法
来源:cnblogs  作者:Danvie  时间:2019/10/8 9:05:25  对本文有异议

今天小编要分享的还是Android Jetpack库的基本使用方法,本篇介绍的内容是Jetpack Navigation组件,让我们一起学习,为完成年初制定的计划而努力吧!



组件介绍

导航,是指提供用户在应用程序中的不同内容之间进行浏览、退出的交互功能。如我们在Android手机上常常用到的物理/虚拟返回按键、桌面(Home)键、历史记录(Recent)键、ActionBar 返回键等等。

Jetpack库中的Navigation组件由以下三个关键部分组成:

  • 导航图:一种XML资源,包含所有与导航有关的信息,如Fragment配置、跳转行为/方向、动画等等;

  • NavHost:一个空容器,用于显示导航图中的目的地,项目中需要包含一个实现NavHost接口的默认NavHostFragment容器;

  • NavController:在NavHost容器内管理应用程序的导航行为。当用户在应用程序中切换界面时,NavController协调容器中的目标内容交换。

优点

使用导航组件有很多好处:

  • 能够处理Fragment切换

  • 能够正确处理向上、返回的默认行为

  • 提供动画和过渡的标准化资源

  • 提供深层链接功能

  • 包含导航UI模式,例如抽屉导航和底部导航,开发者无需进行额外的处理

  • 保护导航之间数据传递的类型安全

  • 提供ViewModel支持,多Fragment间可共享ViewModel数据

  • 提供AndroidStudio图形化查看/编辑导航功能(>= 3.3版本)

简单使用

下面是一个使用导航组件进行开发的Demo运行效果:




从实现效果上来看,整个应用程序共有8个界面,分别是主界面、注册界面、排行界面、用户匹配、游戏界面、失败界面、成功界面、用户界面。

主要涉及的逻辑有:

  • 打开应用进入主界面

  • 主界面提供两个功能,一个开始注册;另一个进入排行界面

  • 注册界面提供开始匹配功能

  • 用户匹配提供开始游戏功能

  • 游戏界面操作后会进入成功或失败界面

  • 游戏成功界面可进入排行界面或匹配界面继续游戏

  • 游戏失败界面可返回到匹配界面重试

  • 排行界面可进入用户界面查看信息

好了,整个应用界面之间涉及的主要逻辑都已经理清楚了,开始导入Jetpack导航组件。

环境配置

  • 使用AS 3.3及以上版本

  • 添加依赖项支持

  1. implementation deps.navigation.fragment_ktx
  2. implementation deps.navigation.runtime_ktx
  3. //implementation "androidx.navigation:navigation-fragment-ktx:2.1.0"
  4. //implementation "androidx.navigation:navigation-ui-ktx:2.1.0"

导航图

导航图的创建是整个应用的核心所在,它描述了所有行为的触发顺序。通过AS Design功能可看到整个应用的界面并且覆盖所有界面可能执
行的顺序。





navigation demo导航图


使用AndroidStudio创建导航图时,选择Resource type为navigation,默认会创建res/navigation目录,并将资源文件放置于此目录下。

以title_screen主界面配置为例,来看一下xml的构成:

  1. <navigation ...
  2. //指定了启动当前导航时显示的界面
  3. app:startDestination="@+id/title_screen">
  4. <fragment
  5. android:id="@+id/title_screen"
  6. android:name="com.example.android.navigationsample.TitleScreen"
  7. android:label="fragment_title_screen"
  8. tools:layout="@layout/fragment_title_screen">
  9. //每一个action都代表了界面上提供跳转到其他界面的行为
  10. <action
  11. android:id="@+id/action_title_screen_to_register"
  12. app:destination="@id/register"
  13. app:popEnterAnim="@anim/slide_in_left"
  14. app:popExitAnim="@anim/slide_out_right"
  15. app:enterAnim="@anim/slide_in_right"
  16. app:exitAnim="@anim/slide_out_left"/>
  17. //设置了动画和过渡效果
  18. <action
  19. android:id="@+id/action_title_screen_to_leaderboard"
  20. app:destination="@id/leaderboard"
  21. app:popEnterAnim="@anim/slide_in_left"
  22. app:popExitAnim="@anim/slide_out_right"
  23. app:enterAnim="@anim/slide_in_right"
  24. app:exitAnim="@anim/slide_out_left"/>
  25. </fragment>
  26. .../>


在导航图配置时,有四个需要注意的属性:

  • popUpTo

  • popUpToInclusive

  • launchSingleTop

  • deepLink

  1. //launchSingleTop代表启动当前fragment后,会栈顶复用
  2. <action
  3. android:id="@+id/action_register_to_match"
  4. app:destination="@id/match"
  5. app:enterAnim="@anim/slide_in_right"
  6. app:exitAnim="@anim/slide_out_left"
  7. app:launchSingleTop="true"
  8. app:popEnterAnim="@anim/slide_in_left"
  9. app:popExitAnim="@anim/slide_out_right" />
  1. //deepLink及深度链接,应用可通过Uri方式启动当前Fragment:
  2. //holder.item.findNavController().navigate(Uri.parse("https://www.example.com/user/Flo"))
  3. //此种方法为静态配置,动态配置方法请参考官方说明文档
  4. <fragment
  5. android:id="@+id/user_profile"
  6. android:name="com.example.android.navigationsample.UserProfile"
  7. android:label="fragment_user_profile"
  8. tools:layout="@layout/fragment_user_profile">
  9. <argument android:name="userName"
  10. android:defaultValue="name"/>
  11. <deepLink app:uri="www.example.com/user/{userName}" />
  12. </fragment>
  1. <action
  2. android:id="@+id/action_in_game_to_resultsWinner"
  3. app:destination="@id/results_winner"
  4. app:popUpTo="@+id/match"
  5. app:popUpToInclusive="false"
  6. app:popEnterAnim="@anim/slide_in_left"
  7. app:popExitAnim="@anim/slide_out_right"
  8. app:enterAnim="@anim/fade_in"
  9. app:exitAnim="@anim/fade_out"/>
  10. //popUpTo属性表示堆栈返回到某个界面,其后的栈数据清空
  11. //popUpToInclusive属性为true表示回到指定界面时,界面栈中是否还包括当前界面
  12. //(如果栈中已经包含了指定要跳转的界面,那么只会保留一个,不指定则栈中会出现两个
  13. //界面相同的Fragment数据)

AndroidManifest与布局文件配置

如果要使用导航组件的深度链接功能,则需要在AndroidManifest中声明导航图,以便深度链接功能正常使用。

  1. <activity...
  2. <nav-graph android:value="@navigation/navigation" />
  3. ...
  4. </activity>

导航功能的使用需要在NavHostFragment容器中实现,因此需要指定布局显示时使用的容器,设置默认NavHost,设置导航图。

  1. <layout>...
  2. <fragment
  3. android:id="@+id/my_nav_host_fragment"
  4. android:name="androidx.navigation.fragment.NavHostFragment"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. app:defaultNavHost="true"
  8. app:layout_constraintBottom_toBottomOf="parent"
  9. app:layout_constraintEnd_toEndOf="parent"
  10. app:layout_constraintStart_toStartOf="parent"
  11. app:layout_constraintTop_toTopOf="parent"
  12. app:navGraph="@navigation/navigation"/>
  13. .../>

代码实现

整个Demo使用单Activity,多Fragment架构,MainActivity启动时,加载NavHostFragment容器,解析navigation容器图,通过startDestination属性找到首界面进行显示(本例首界面为TitleScreen)。

如下为TitleScreen的代码实现:

  1. class TitleScreen : Fragment() {
  2. override fun onCreateView(
  3. inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
  4. ): View? {
  5. val view = inflater.inflate(R.layout.fragment_title_screen, container, false)
  6. view.findViewById<Button>(R.id.play_btn).setOnClickListener {
  7. Navigation.findNavController(view).navigate(R.id.action_title_screen_to_register)
  8. }...
  9. return view
  10. }
  11. }

到此,使用导航组件进行应用程序开发的基本流程已经结束,当然导航组件提供的功能远不止如此,它还有如页面间数据类型的安全保护,手势导航,导航嵌套、条件导航,自定义动画过渡效果,使用NavigationUI更新界面等高级使用方法。具体使用可参考Google官方文档说明。

源码在此

- END -



欢迎关注公众号,留言讨论更多技术问题


file

原文链接:http://www.cnblogs.com/danvie/p/11631084.html

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号