Navigation Architecture Component 1

1.Introduce

導(dǎo)航組件簡化了導(dǎo)航的實(shí)現(xiàn),也可以實(shí)現(xiàn)導(dǎo)航流程的可視化。navigation庫提供了一系列便捷:

  • 自動處理fragment transactions
  • Correctly handling up and back by default
  • Default behaviors for animations and transitions
  • Deep linking as a first class operation
  • 只需要一點(diǎn)點(diǎn)額外工作就可以實(shí)現(xiàn)導(dǎo)航UI模板(就像navigation drawers 和 bottom nav)
  • Type safety when passing information while navigating
  • Android studio提供了app導(dǎo)航的可視化和導(dǎo)航流的編輯

BEHOLD:


1.gif

2.Getting Start

$ git clone https://github.com/googlecodelabs/android-navigation

Navigation概述

導(dǎo)航組件包括三個關(guān)鍵部分:
  • Navigation Graph(新的xml資源) :This is a resource that contains all navigation-related information in one centralized location. This includes all the places in your app, known as destinations, and possible paths a user could take through your app
  • NavHostFragment(XML布局視圖):This is a special widget you add to your layout. It displays different destinations from your Navigation Graph.
  • NavController(一個Object):This is an object that keeps track of the current position within the navigation graph. It orchestrates swapping destination content in the NavHostFragment as you move through a navigation graph.

3.Introduce the Navigation Graph

Destinations(目的地)

導(dǎo)航組件引入了Destination的概念。Destination是應(yīng)用中可以導(dǎo)航到達(dá)的任意位置,一般來講是一個fragment或者activity。These are supported out of the box, but you can also make your own custom destination types if needed。

Navigation Graph(導(dǎo)航圖)

導(dǎo)航圖是一種新的資源類型,定義了應(yīng)用中用戶可以使用的所有路徑。它直觀地顯示了一個目的地(Destination)可以到達(dá)的所有其他的目的地。下面是練習(xí)中導(dǎo)航的起始狀態(tài):


image.png
Navigation Editor(導(dǎo)航編輯器)
  1. 打開 res/navigation/mobile_navigation.xml
  2. 點(diǎn)Design
    image.png

    image.png

    destination之間的箭頭叫做action,這個我們晚一點(diǎn)討論。
  3. 點(diǎn)擊一個destination查看屬性


    image.png

    4.查看action的屬性,點(diǎn)擊箭頭就可以了

分析navigation的XML文件
<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"
    app:startDestination="@+id/home_dest">

<!-- ...tags for fragments and activities here -->

</navigation>
  • <navigation>是導(dǎo)航圖的根節(jié)點(diǎn)

  • <navigation>包含一個或多個destination,<activity>或<fragment>

  • app:startDestination定義app打開時默認(rèn)加載的destination
    下面是一個fragment destination

      <fragment
          android:id="@+id/flow_step_one_dest"   
          android:name="com.example.android.codelabs.navigation.FlowStepFragment"
    
          tools:layout="@layout/flow_step_one_fragment">
          <argument
          .../>
    
          <action
              android:id="@+id/next_action"
              app:destination="@+id/flow_step_two_dest">
          </action>
      </fragment>
    
  • android:id 就是一個id

  • android:name 引用的fragment的全路徑

  • tools:layout 導(dǎo)航圖中顯示的布局哦

4.給Navigation Graph添加一個Destination

  • 打開mobile_navigation.xml,進(jìn)入design模式
  • 點(diǎn)擊new Destination,選擇settings_fragment

5.使用導(dǎo)航圖進(jìn)行導(dǎo)航

Activity和Navigation

導(dǎo)航組件遵循著Principles of Navigation中敘述的指導(dǎo)思想。指導(dǎo)中提到應(yīng)該用activity作為app的入口,而且activity中應(yīng)該包含全局導(dǎo)航,比如bottom nav,
比較下來, fragments will be the actual destination-specific layouts.
To get this all to work,需要讓activity包含一個叫做NavHostFragment的特殊部件。一個NavHostFragment會根據(jù)導(dǎo)航圖中的導(dǎo)航交換不同的fragment destination。

image.png

舉個栗子:

<LinearLayout
.../>
    <androidx.appcompat.widget.Toolbar
        .../>
    <fragment
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/my_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/mobile_navigation"
        app:defaultNavHost="true"
    />
    <com.google.android.material.bottomnavigation.BottomNavigationView
    .../>
</LinearLayout>
  • 以上是一個activity的layout,包含了全局導(dǎo)航:一個bottom nav和一個toolbar
  • android:name="androidx.navigation.fragment.NavHostFragment"和app:defaultNavHost="true"把系統(tǒng)后退按鈕連接到NavHostFragment
  • app:navGraph="@navigation/mobile_navigation"將HavHostFragment和導(dǎo)航圖關(guān)聯(lián)起來,導(dǎo)航圖中定義了在NavHostFragment中可以導(dǎo)航的所有destinatioin
NavController

當(dāng)用戶進(jìn)行一些操作,比如點(diǎn)擊了某個按鈕,就需要觸發(fā)導(dǎo)航命令,NavController就是觸發(fā)NavHostFragment交互fragment的指定類。

// Command to navigate to flow_step_one_dest
findNavController().navigate(R.id.flow_step_one_dest)

這里傳入destination的id或者action的id都可以哦。

NavController很強(qiáng)大的,當(dāng)調(diào)用navigate()或者popBackStack()時,它會把這些命令根據(jù)destination的來(from)或去(to)轉(zhuǎn)換成適當(dāng)?shù)目蚣懿僮?。比如,?dāng)對一個activity destination調(diào)用navigation()時,NavController會調(diào)用startActivity()。

獲取與NavHostFragment相關(guān)的NavController有幾個途徑。在Kotlin中,根據(jù)在fragment,activity或者view中獲取NavController,推薦從以下選擇:

使用NavContriller導(dǎo)航去一個Destination

是時候表演真正的技術(shù)了,現(xiàn)在將要點(diǎn)擊“Navigate To Destination”按鈕導(dǎo)航去flow_step_one_dest destination(FlowStepFragment):

  • 打開HomeFragment.kt
  • 在onViewCreated()中搞navigate_destination_button
val button = view.findViewById<Button>(R.id.navigate_destination_button)
button?.setOnClickListener {
    findNavController().navigate(R.id.flow_step_one_dest)
}

或者

val button = view.findViewById<Button>(R.id.navigate_destination_button)
button?.setOnClickListener(     Navigation.createNavigateOnClickListener(R.id.flow_step_one_dest, null)
)

都可以

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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