使用jetpack navigation管理fragment

一、什么是navigation

要說什么是navigation就要先說說fragment這個東西。fragment最早出現(xiàn)在Android 3.0,它的出現(xiàn)主要伴隨著兩個目的:

  1. 用于適配當時搭載蜂巢的Android平板設(shè)備,讓其在更大的屏幕上能夠在一個activity嵌套多個不同的頁面,充分的利用大屏的顯示優(yōu)勢。
image
image
  1. 分散activity的壓力,對其解耦,讓部分UI內(nèi)容由各個fragment獨自管理。

fragment有非常多的優(yōu)勢,它本身是一個VIew派生而來的控件,嵌套靈活,渲染所消耗的資源明顯小于activity,數(shù)據(jù)的傳遞也更加方便,當然它的優(yōu)點并不止這些,

以至于包括知乎、Google全家桶在內(nèi)的眾多App都發(fā)展出了單Activity+多fragment的方式開發(fā)UI,這其中的優(yōu)勢,在知乎的一個問題下有著非常多討論。https://www.zhihu.com/question/39662488

但是在在這些應(yīng)用開發(fā)的過程中,開發(fā)者們也發(fā)現(xiàn)了不少這種做法帶來的坑。例如需要維護復(fù)雜的fragment回退棧、使用不當?shù)那闆r下經(jīng)常出現(xiàn)fragment重疊、經(jīng)常由于activity已經(jīng)銷毀導致使用上下文crash、

等等等等的問題。

而navigation就是為了解決這些問題而出現(xiàn)的,用于實現(xiàn)單activity多fragment形式的官方解決方案。

navigation是jetpack組件庫的一部分,jetpack的前生其實就是我們所熟悉的support library,Google在不久前宣布support library將只維護到v28,之后將全面遷移到androidx(也就是jetpack)。

二、添加navigation支持

navigation的使用限制實際上是比較多的。

  1. 保證你的Android studio版本 >=3.2
  2. 保證項目的gradle版本>=3.2


    image
    image
  3. 保證項目sdk的版本>=28


    image
    image
  4. 將你的項目從support library 向 androidx遷移,這一點工程量比較大,所以Google在新版studio添加了一鍵遷移程序。
image
image
  1. 確保studio打開了navigation的支持,在設(shè)置中確保如下開關(guān)是打開的。
image
image

這幾步你都做完了嗎?做完了就可以在你的gradle下添加navigation的依賴了。

implementation "android.arch.navigation:navigation-fragment:1.0.0-alpha07"
implementation "android.arch.navigation:navigation-ui:1.0.0-alpha07" 

三、使用navigation

使用起來其實蠻簡單的 ,首先在res目錄下新建一個android resource file ,名稱有意義即可,resource type 選擇 navigation

image
image

得到這樣一個文件,由于還沒有任何的頁面,所以只有一個節(jié)點navigation

image
image

打開下方的design視圖,可以看到什么都沒有,這時可以通過左上角的+號來
image.png

新增頁面。這里既然要跳轉(zhuǎn),我們新增兩個fragment。

選中一個頁面的時候,右側(cè)會有針對這個fragment的屬性面板,而fragment本身會出現(xiàn)一個小圓點,此時我們就可以拖拽這個小圓點去連接其他的頁面,連接上就表示建立了跳轉(zhuǎn)關(guān)系了。

image.png

這時打開text視圖可以看到多了兩個fragment節(jié)點,并且在第一個fragment節(jié)點下多了一個action。

之后我們的跳轉(zhuǎn)就需要通過這個action的id來實現(xiàn)了。

現(xiàn)在打開BlankFragment的布局,為其添加一個用于跳轉(zhuǎn)的按鈕。

image.png
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             tools:context=".BlankFragment">
    <Button
            android:id="@+id/mJumpBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="jump to second fragment"/>
</FrameLayout>

在fragment中,該按鈕點擊事件被觸發(fā)后,使用Navigation調(diào)用findNavController傳入觸發(fā)事件的view的對象獲取到一個NavController對象,調(diào)用其navigate方法傳入前面所提到的action的id,即可完成跳轉(zhuǎn)。

mJumpBtn.setOnClickListener { view ->
   Navigation.findNavController(view).navigate(R.id.action_blankFragment_to_secondFragment)
}

現(xiàn)在fragment之間的跳轉(zhuǎn)已經(jīng)搞定,但是我們卻忘了,fragment還需要依賴activity去展示呢,那么我們找回一開始新建項目得到的MainActivity(沒有的話自己新建一個哦)。

打開MainActivity的布局。在布局中添加一個fragment,注意紅框標注的那兩段代碼,會將我們前面寫好的navigation嵌入進來。

image.png

至此,運行程序,你會發(fā)現(xiàn),展示的第一個頁面是帶有jump to second fragment 按鈕的BlankFragment,點擊它會跳轉(zhuǎn)到第二個SecondFragment。觸摸手機的返回鍵會返回到上一個頁面,和activity幾乎一樣。

如果你使用的是toolbar,那么可以直接綁定這兩個控件來完成toolbar返回的操作,如果不是,那么你可以在SecondFragment中獲取到NavController并調(diào)用navigateUp方法來返回上一個頁面

 mBackBtn.setOnClickListener {
   Navigation.findNavController(it).navigateUp()
 }

四、傳遞參數(shù)

傳遞參數(shù)其實很簡單,和我們之前傳遞的方式其實類似,同樣是使用bundle來傳遞。

傳遞

 mJumpBtn.setOnClickListener { view ->
     Navigation.findNavController(view).navigate(R.id.action_blankFragment_to_secondFragment, Bundle().apply {
         putString("name", "tracy")
         putInt("age", 35)
     })
 }

接收

 arguments?.let {
      Log.i("日志", it.getString("name"))
      Log.i("日志", it.getInt("age", 0) + "")
 }

五、其他能力

當然,navigation所提供的能力遠不止這些。

在傳參方面它可以通過gradle插件的方式為我們提供更可靠安全的數(shù)據(jù)傳遞。

它能更簡單的為fragment添加跳轉(zhuǎn)動畫

它能讓fragment實現(xiàn)共享元素動畫

它能通過Deep Link直接路由到fragment

它能直接與androidx組件中的 NavigationView(對,就是側(cè)滑抽屜用的那個)進行菜單聯(lián)動

它能和menu浮層菜單進行聯(lián)動

也能和toolbar進行聯(lián)動

此文只講解了比較基礎(chǔ)的使用方式,還有很多功能請查看api哈。

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

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

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