这是一篇Navigation配合ActionBar使用的一篇文章,主要讲述了在使用Navigation时,绑定ActionBar配合导航的一些使用方法。
如果想了解一些Navigation的基础用法。可以先去看看我之前的一篇文章《Android Jetpack-Navigation初见》。
其实这个想法主要也是来自于Ios的NavigationController,而且ActionBar也是android系统推荐的一款很不错的导航工具,当然你也可以使用你自定义的导航栏,他们的原理是相同的。
创建一个Navigation的项目,大致结构如下(如果不清楚如何创建可以去查看下文章头部的我的另外一篇博客):
2.在HostActivity中添加逻辑代码,添加后的Activity大致如下(Kotlin)
class MainActivity : AppCompatActivity() { private val navController: NavController? get() { return try { Navigation.findNavController(this, R.id.fragmentNavigation) } catch (e: Exception) { e.printStackTrace() null } } override fun onSupportNavigateUp() = navController?.navigateUp() ?: false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) navController?.addOnNavigatedListener { controller, destination -> val graph = controller.graph supportActionBar?.setDisplayHomeAsUpEnabled( destination != graph.findNode(graph.startDestination)) } } }
需要注意两点:
a.在AppCompatActivity.onSupportNavigateUp方法中返回NavController.navagateUp()。去支持系统的向上操作。
b.在onCreate中添加导航事件的回调监听,在当前的Fragment不是startDestination的时候显示ActionBar的后退按钮。
就这样,ActionBar就能简单的实现后退事件和Navigation绑定了。
但是这样看起来还是很怪。因为ActionBar的Title在跳转的时候依然是不变的。这样的话就需要在Fragment显示的时候去手动的改变Actionbar的title,这样看起来并不是那么优美。查看了下nav_graph里fragment的属性。发现这个fragment标签中,有label属性。那这个label属性为什么不能直接当作标题使用呢。(对,模仿NavigationCotroller就要模仿的像一些嘛。哈哈)
如果像要实现上面的方案需要怎么做呢。
只需要在nav_graph.xml中为每个fragment标签加入label属性
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" app:startDestination="@id/fragmentStep1"> <fragment android:id="@+id/fragmentStep1" android:name="com.example.xwh.myapplication.FragmentStep1" tools:layout="@layout/fragment_step1" android:label="FragmentStep1" > <action android:id="@+id/action_step1_to_step2" app:destination="@+id/fragmentStep2" app:enterAnim="@anim/nav_default_enter_anim" app:exitAnim="@anim/nav_default_exit_anim" app:popEnterAnim="@anim/nav_default_pop_enter_anim" app:popExitAnim="@anim/nav_default_pop_exit_anim" /> </fragment> <fragment android:id="@+id/fragmentStep2" tools:layout="@layout/fragment_step2" android:name="com.example.xwh.myapplication.FragmentStep2" android:label="FragmentStep2" > <action android:id="@+id/action_fragmentStep2_to_fragmentStep3" app:destination="@id/fragmentStep3" app:enterAnim="@anim/nav_default_enter_anim" app:exitAnim="@anim/nav_default_exit_anim" app:popEnterAnim="@anim/nav_default_pop_enter_anim" app:popExitAnim="@anim/nav_default_pop_exit_anim" /> </fragment> <fragment android:id="@+id/fragmentStep3" tools:layout="@layout/fragment_step3" android:name="com.example.xwh.myapplication.FragmentStep3" android:label="FragmentStep3" /> </navigation>
并且在HostActivty中在Navigation的监听对象中改变ActionBar的title就可以了
navController?.addOnNavigatedListener { controller, destination -> supportActionBar?.title = destination.label val graph = controller.graph supportActionBar?.setDisplayHomeAsUpEnabled( destination != graph.findNode(graph.startDestination)) }
当然,你也可以使用Fragment的Tag属性,或者使用你自定义的Fragment中的自定义属性都可以。