写点什么

Android 开发之深入浅出 NavigationUI,2020-2021 阿里巴巴安卓面试真题解析

用户头像
Android架构
关注
发布于: 刚刚


在之前的?导航系列文章中,Chet?开发了一个用于?跟踪甜甜圈的应用。知道什么是甜甜圈的最佳搭档吗?(难道是另一个甜甜圈?) 当然是咖啡!所以我准备增加一个追踪咖啡的功能。我需要在应用中增加一些页面,所以有必要使用抽屉式导航栏或者底部标签栏来辅助用户导航。但是我们该如何使用这些 UI 组件来集成导航功能呢?通过点击监听器手动触发导航动作吗?


不需要!无需任何监听器。NavigationUI 类通过匹配目标页面 id 与菜单 id 实现不同页面之间的导航功能。让我们深入探索一下它的内部机制吧。


添加咖啡追踪器





△ 工程结构


首先我将与甜甜圈相关的类文件拷贝了一份到新的包下,并且将它们重命名。这样的操作对于真正的应用来说也许不是最好的做法,但是在这里可以快速帮助我们添加咖啡跟踪功能到已有的应用中。如果您希望随着文章内容同步操作,可以获取?这里的代码,里面包含了全部针对 Donut Tracker 应用的修改,可以基于该代码了解 NavigationUI。


基于上面所做的修改,我更新了导航图,新增了从 coffeeFragment 到 coffeeDialogFragment 以及从 selectionFragment 到 donutFragment 相关的目的页面和操作。之后我会用到这些目的页面的 id ;)



△ 带有新的目的页面的导航图


更新导航图之后,我们可以开始将元素绑定起来,并且实现导航到 SelectionFragment。


选项菜单




应用的选项菜单现在尚未发挥作用。要启用它,需要在?onOptionsItemSelected()?函数中,为被选择的菜单项调用?onNavDestinationSelected()?函数,并传入?navController。只要目的页面的?id?和?MenuItem?的 id 相匹配,该函数会导航到绑定在?MenuItem?上的目的页面。


override fun onOptionsItemSelected(item: MenuItem): Boolean {


return item.onNavDestinationSelected(


findNavController(R.id.nav_host_fragment)


) || super.onOptionsItemSelected(item)


}


现在导航控制器可以 "支配" 菜单项了,我将?MenuItem?的?id?与之前所创建的目的页面的?id?进行了匹配。这样,导航组件就可以将?MenuItem?与目的页面进行关联。


<menu xmlns:android="http://schemas.android.com/apk/res/android"


xmlns:app="http://schemas.android.com/apk/res-auto"


xmlns:tools="http://schemas.android.com/tools"


tools:context="com.android.samples.donuttracker.MainActivity">


<item


android:id="@+id/selectionFragment"


android:orderInCategory="100"


android:title="@string/action_settings"


app:showAsAction="never" />


</menu>


Toolbar




现在应用可以


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


导航到?selectionFragment,但是标题仍然保持原样。当处于?selectionFragment?的时候,我们希望标题可以被更新并且显示返回按钮。


首先我需要添加一个?AppBarConfiguration?对象,NavigationUI?会使用该对象来管理应用左上角的导航按钮的行为。


appBarConfiguration = AppBarConfiguration(navController.graph)


该按钮会根据您的目的页面的层级改变自身的行为。比如,当您在最顶层的目的页面时,就不会显示回退按钮,因为没有更高层级的页面。


默认情况下,您应用的最初页面是唯一的最顶层目的页面,但是您也可以定义多个最顶层目的页面。比如,在我们的应用中,我可以将?donutList??coffeeList?的目的页面都定义为最顶层的目的页面。


接下来,在?MainActivity?类中,获得?navController?和?toolbar?的实例,并且验证?setSupportActionBar()?是否被调用。这里我还更新了传入函数的 toolbar 的引用。


val navHostFragment = supportFragmentManager.findFragmentById(


R.id.nav_host_fragment


) as NavHostFragment


navController = navHostFragment.navController


val toolbar = binding.toolbar


要在默认的操作栏 (Action Bar) 中添加导航功能,我在这里使用了?setupActionBarWithNavController()?函数。该函数需要两个参数:?navController?和?appBarConfiguration


setSupportActionBar(toolbar)


setupActionBarWithNavController(navController, appBarConfiguration)


接下来,根据目前的目的页面,我覆写了?onSupportNavigationUp()?函数,然后在?nav_host_fragment?上调用?navigateUp()?并传入?appBarConfiguration?来支持回退导航或者显示菜单图标的功能。


override fun onSupportNavigateUp(): Boolean {


return findNavController(R.id.nav_host_fragment).navigateUp(


appBarConfiguration


)


}


现在我可以导航到 selectionFragment,并且您可以看到标题已经更新,并且也显示了返回按钮,用户可以返回到之前的页面。



△ 标题更新了并且也显示了返回按钮


底部标签栏




目前为止还算顺利,但是应用还不能导航到?coffeeList?Fragment。接下来我们将解决这个问题。


我们从添加底部标签栏入手。首先添加?bottom_nav_menu.xml?文件并且声明两个菜单元素。NavigationUI?依赖?MenuItem?的?id,用它与导航图中目的页面的 id 进行匹配。我还为每个目的页面设置了图标和标题。


<menu xmlns:android="http://schemas.android.com/apk/res/android">


<item


android:id="@id/donutList"


android:icon="@drawable/donut_with_sprinkles"


android:title="@string/donut_name" />


<item


android:id="@id/coffeeList"


android:icon="@drawable/coffee_cup"


android:title="@string/coffee_name" />


</menu>


现在?MenuItem?已经就绪,我在?mainActivity?的布局中添加了?BottomNavigationView,并且将?bottom_nav_menu?设置为?BottomNavigationView的?menu?属性。


<com.google.android.material.bottomnavigation.BottomNavigationView


android:id="@+id/bottom_nav_view"


android:layout_width="match_parent"


android:layout_height="wrap_content"


app:menu="@menu/bottom_nav_menu" />


要使底部标签栏发挥作用,这里调用?setupWithNavController()?函数将?navController?传入?BottomNavigationView


private fun setupBottomNavMenu(navController: NavController) {


val bottomNav = findViewById<BottomNavigationView>(


R.id.bottom_nav_view


)


bottomNav?.setupWithNavController(navController)

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android 开发之深入浅出 NavigationUI,2020-2021阿里巴巴安卓面试真题解析