NavigationUI对3种类型的App bar提供了支持,分别是ActionBar、Toolbar和CollapstingToolbarLayout。另外,除了最常见的menu菜单,NavigationUI还可以配合App bar左侧的抽屉菜单(DrawLayout+NavigationView)和底部菜单(BottomNavigationView)。
现在需要实现以下功能:有MainFragment和SecondFragment,这两个Fragment同属于NavigationTestMainActivity。在MainFragment的ActionBar有一个按钮,点击按钮跳转到SecondFragment,之后点击SecondFragment的ActionBar上的返回按钮,返回到MainFragment。
修改Android_Jetpack:Navigation初见以及使用safe args插件传递参数项目中的代码。
首先在res目录下添加menu目录,之后新建menu_main_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@id/secondFragment"
android:title="跳转到Second"
android:icon="@drawable/ic_launcher_foreground"/>
</menu>
这里需要注意的是,android:id要与nav_graph导航图中SecondFragment的id要一致,因为当这个item被点击时,将会跳转到id所对应的Fragment。
在NavigationTestMainActivity中实例化这个菜单。
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main_fragment,menu)
return true
}
接下来编写相应点击事件的代码。由于引入了NavigationUI,省去了判断被单击菜单项的步骤,可以直接编写跳转代码。
class NavigationTestMainActivity : AppCompatActivity() {
lateinit var appBarConfiguration: AppBarConfiguration
lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation_test_main)
navController = Navigation.findNavController(this,R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(navController.graph)
//将App bae和NavController绑定
NavigationUI.setupActionBarWithNavController(this,navController,appBarConfiguration)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main_fragment,menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return NavigationUI.onNavDestinationSelected(item,navController)||
super.onOptionsItemSelected(item)
}
//onSupportNavigateUp可以使用toolbar的后退按钮后退,覆盖此方法,当在SecondFragment中点击ActionBar
// 返回按钮时,NavigationUI主动使SecondFragment返回到MainFragment
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController,appBarConfiguration)||
super.onSupportNavigateUp()
}
}
由于ActionBar是在NavigationTestMainActivity中进行管理的,所以在跳转到SecondFragment时,需要覆盖SecondFragment的onCreateOptionsMenu()方法,清除MainFragment中对应的menu。
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
menu.clear()//清除menu
super.onCreateOptionsMenu(menu, inflater)
}
别忘了在onCreate方法中添加
setHasOptionsMenu(true)
使菜单生效。
另外,NavController提供了一个名为addOnDestinationChangedListener的接口,可以对页面切换事件进行监听,代码如下:
navController.addOnDestinationChangedListener {
controller, destination, arguments ->
//收到切换事件
Log.d("listener","$controller\n$destination\n$arguments")
}