Jetpack組件-Navigation構(gòu)成+使用

背景:Google 在2018年推出的 Android Jetpack中有一種新架構(gòu)模式,那就是navigation,字面意思是導(dǎo)航。但是除了做APP引導(dǎo)頁面以外,它也可以使用在App主頁分tab的情況,甚至可以一個(gè)功能模塊就一個(gè)activity大部分頁面UI都使用fragment來實(shí)現(xiàn)。因此,navigation就成了管理fragment至關(guān)重要的架構(gòu)。

一、Navigation三大構(gòu)成

  1. Navigation Graph:Navigaion Graph(導(dǎo)航圖)是一個(gè) XML 文件,定義了應(yīng)用程序中所有可導(dǎo)航的目標(biāo)(如 Fragment、Activity 或自定義目標(biāo)),以及它們之間的導(dǎo)航關(guān)系。包含所有被管理的 Fragment,起始目標(biāo),換頁目標(biāo),返回目標(biāo)等。
  2. NavHostFragment:NavHostFragment 是一個(gè)托管 Fragment 的容器,用于管理應(yīng)用程序中的導(dǎo)航圖。(注:它本質(zhì)是一個(gè)特殊的Fragment)
<fragment
        android:id="@+id/navHostFragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNaHost="true"
        app:navGraph="@navigation/nav_graph_main" />

  1. NavController:NavController 是用于管理導(dǎo)航操作的控制器,它負(fù)責(zé)根據(jù)導(dǎo)航圖中定義的導(dǎo)航關(guān)系,自動(dòng)切換目標(biāo) Fragment,并將其添加到回退棧中,以便用戶可以通過返回按鈕回退到上一個(gè)目標(biāo)。通常是寫在點(diǎn)擊事件內(nèi)完成 Fragment 的切換。
button.setOnClickListener {
    findNavController().navigate(R.id.action_Fragment1_to_Fragment2)
  }

二、基本使用

  1. 添加依賴庫
    implementation("androidx.navigation:navigation-fragment-ktx:2.5.1")
    implementation("androidx.navigation:navigation-ui-ktx:2.5.1")

2.創(chuàng)建導(dǎo)航視圖

  • 右鍵res,點(diǎn)擊New -> Android Resource Directory
  • 在出現(xiàn)的面板第二行Resource type 下拉列表中選擇 Navigation,然后點(diǎn)擊 OK
  • res目錄下會(huì)多出一個(gè)navigation的資源目錄,右鍵該目錄,點(diǎn)擊New -> Navigation Resource File,輸入需要新建的資源文件名,這里命名nav_graph,點(diǎn)擊ok,一個(gè)nav_graph.xml就創(chuàng)建好了。
  1. 配置graph及fragment之間的關(guān)系(如創(chuàng)建A/B/C三個(gè)fragment)
<?xml version="1.0" encoding="utf-8"?>
<navigation 
    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"
    android:id="@+id/nav_graph"
    app:startDestination="@id/fragmentA">

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.example.testnavigation.FragmentA"
        android:label="fragment_a"
        tools:layout="@layout/fragment_a" >
        <action
            android:id="@+id/action_fragmentA_to_fragmentB2"
            app:destination="@id/fragmentB" />
    </fragment>
    <fragment
        android:id="@+id/fragmentB"
        android:name="com.example.testnavigation.FragmentB"
        android:label="fragment_b"
        tools:layout="@layout/fragment_b" >
        <action
            android:id="@+id/action_fragmentB_to_fragmentC2"
            app:destination="@id/fragmentC" />
    </fragment>
    <fragment
        android:id="@+id/fragmentC"
        android:name="com.example.testnavigation.FragmentC"
        android:label="fragment_c"
        tools:layout="@layout/fragment_c" />
</navigation>
  • navigation是根標(biāo)簽,通過startDestination配置默認(rèn)啟動(dòng)的第一個(gè)頁面,這里配置的是FragmentA
  • fragment標(biāo)簽代表一個(gè)fragment,其實(shí)這里不僅可以配置fragment,也可以配置activity,甚至還可以自定義
  • action標(biāo)簽定義了頁面跳轉(zhuǎn)的行為,相當(dāng)于上圖中的每條線,destination定義跳轉(zhuǎn)的目標(biāo)頁,還可以定義跳轉(zhuǎn)時(shí)的動(dòng)畫等等(當(dāng)調(diào)用到 action_FragmentA_to_FragmentB2 這個(gè) action,會(huì)從 FragmentA -> FragmentB)
  1. 添加NaviHostFragment
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />

</androidx.constraintlayout.widget.ConstraintLayout>

  • android:name指定NavHostFragment
  • app:navGraph指定導(dǎo)航視圖,即建好的nav_graph.xml
  • app:defaultNavHost=true意思是可以攔截系統(tǒng)的返回鍵,可以理解為默認(rèn)給fragment實(shí)現(xiàn)了返回鍵的功能,這樣在fragment的跳轉(zhuǎn)過程中,當(dāng)我們按返回鍵時(shí),就可以使得fragment跟activity一樣可以回到上一個(gè)頁面了
  1. 通過NaviController管理fragment之間的跳轉(zhuǎn)
  • 例如從fragmentA跳轉(zhuǎn)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    button.setOnClickListener {
        val navController = Navigation.findNavController(it)
        navController.navigate(R.id.action_fragmentA_to_fragmentB2)
    }
}
  • 首先得到navController對(duì)象,然后調(diào)用它的navigate方法,傳入前面nav_graph中定義的action的id即可。
  • 可以在nav_graph中調(diào)整pop屬性來更改出入棧順序
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容