Android-Jetpack:Navigation配合ActionBar使用

这是一篇Navigation配合ActionBar使用的一篇文章,主要讲述了在使用Navigation时,绑定ActionBar配合导航的一些使用方法。

如果想了解一些Navigation的基础用法。可以先去看看我之前的一篇文章《Android Jetpack-Navigation初见》。

其实这个想法主要也是来自于Ios的NavigationController,而且ActionBar也是android系统推荐的一款很不错的导航工具,当然你也可以使用你自定义的导航栏,他们的原理是相同的。

创建一个Navigation的项目,大致结构如下(如果不清楚如何创建可以去查看下文章头部的我的另外一篇博客):

Android-Jetpack:Navigation配合ActionBar使用_第1张图片

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"?>
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">

            android:id="@+id/fragmentStep1"
        android:name="com.example.xwh.myapplication.FragmentStep1"
        tools:layout="@layout/fragment_step1"
        android:label="FragmentStep1" >
                    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" />
    
            android:id="@+id/fragmentStep2"
        tools:layout="@layout/fragment_step2"
        android:name="com.example.xwh.myapplication.FragmentStep2"
        android:label="FragmentStep2" >
                    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" />
    
            android:id="@+id/fragmentStep3"
        tools:layout="@layout/fragment_step3"
        android:name="com.example.xwh.myapplication.FragmentStep3"
        android:label="FragmentStep3" />

并且在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中的自定义属性都可以。


你可能感兴趣的:(移动开发,Android)