JetPack之Navigation實戰(zhàn)

Navigation 直接翻譯即為導(dǎo)航,它是 Android Jetpack 組件之一箕速,讓單 Activity 應(yīng)用成為首選架構(gòu)躁染。應(yīng)用內(nèi)Fragment頁面的跳轉(zhuǎn)則由 Navigation 來處理城看,開發(fā)者無需在處理 FragmentTransaction 的復(fù)雜性以及相關(guān)的轉(zhuǎn)場動畫。

相比之前Fragment的管理需要借助FragmentManager和FragmentTransaction,使用Navigation組件有如下一些優(yōu)點:

1.可視化的頁面導(dǎo)航圖恐锣,方便我們理清頁面之間的關(guān)系
2.通過destination和action完成頁面間的導(dǎo)航
3.方便添加頁面切換動畫
4.頁面間類型安全的參數(shù)傳遞
5.通過Navigation UI類夹囚,對菜單/底部導(dǎo)航/抽屜藍(lán)菜單導(dǎo)航進行統(tǒng)一的管理

實戰(zhàn)完成效果

使用Navigation

1. 引入依賴

在app的gradle.build中添加依賴:

    nav_version=2.5.0

    // Kotlin
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
2. 了解組成
  • Navigation graph
    一個包含所有導(dǎo)航相關(guān)信息的 XML 資源
    xml 檔,包含所有被管理的 Fragment穴翩,起始目標(biāo)犬第,換頁目標(biāo),返回目標(biāo)芒帕。

  • NavHostFragment
    一種特殊的Fragment歉嗓,用于承載導(dǎo)航內(nèi)容的容器

  • NavController
    用來管理 NavHost 中的導(dǎo)航動作,通常是寫在點擊事件內(nèi)完成 Fragment 的切換副签。

findNavController().navigate(R.id.action_Fragment1_to_Fragment2)
3.開始接入

1.右鍵res遥椿,點擊New -> Android Resource Directory
2.在出現(xiàn)的面板第二行Resource type 下拉列表中選擇 Navigation,然后點擊 OK
3.res目錄下會多出一個navigation的資源目錄淆储,右鍵該目錄冠场,點擊New -> Navigation Resource File,輸入需要新建的資源文件名本砰,這里命名nav_graph碴裙,點擊ok,一個nav_graph.xml就創(chuàng)建好了。

新建好的nav_graph.xml切換到design模式下舔株,點擊2處的加號莺琳,選擇Create new destination,即可快速創(chuàng)建新的Fragment载慈〔训龋或者直接引用已有的fragment做管理。

建好后办铡,可通過手動配置頁面之間的跳轉(zhuǎn)關(guān)系辞做,點擊某個頁面,右邊會出現(xiàn)一個小圓點寡具,拖曳小圓點指向跳轉(zhuǎn)的頁面秤茅,這里設(shè)置跳轉(zhuǎn)的關(guān)系為FragmentA -> FragmentB。

<?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"
    android:id="@+id/nav_graph"
    app:startDestination="@id/navigation_home">

    <fragment
        android:id="@+id/navigation_home"
        android:name="com.example.flowmvihilt.ui.main.MainFragment">

        <action android:id="@+id/action_to_artical"
            app:destination="@id/articalFragment"/>
    </fragment>
    <fragment
        android:id="@+id/navigation_qa"
        android:name="com.example.flowmvihilt.ui.main.MainFragment" />
    <fragment
        android:id="@+id/navigation_system"
        android:name="com.example.flowmvihilt.ui.main.MainFragment"
        android:label="MainFragment" />
    <fragment
        android:id="@+id/navigation_mine"
        android:name="com.example.flowmvihilt.mine.MeFragment"/>
    <fragment
        android:id="@+id/articalFragment"
        android:name="com.example.flowmvihilt.mine.ArticalFragment"/>
</navigation>

navigation是根標(biāo)簽童叠,通過startDestination配置默認(rèn)啟動的第一個頁面框喳,這里配置的是FragmentA
fragment標(biāo)簽代表一個fragment,其實這里不僅可以配置fragment厦坛,也可以配置activity五垮,甚至還可以自定義
action標(biāo)簽定義了頁面跳轉(zhuǎn)的行為,相當(dāng)于上圖中的每條線粪般,destination定義跳轉(zhuǎn)的目標(biāo)頁拼余,還可以定義跳轉(zhuǎn)時的動畫等等
當(dāng)調(diào)用到 action_FragmentA_to_FragmentB2 這個 action,會從 FragmentA -> FragmentB

在Activity的布局文件中配置NavHostFragment和BottomNavigationView
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_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_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:navGraph="@navigation/nav_graph" />

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/nav_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:labelVisibilityMode="labeled"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:itemBackground="@null"
            app:menu="@menu/bottom_nav_menu" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

android:name指定NavHostFragment
app:navGraph指定導(dǎo)航視圖亩歹,即建好的nav_graph.xml
app:defaultNavHost=true意思是可以攔截系統(tǒng)的返回鍵匙监,按返回鍵可以回到上一個頁面

menu文件:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_launcher_foreground"
        android:title="@string/home_page" />

    <item
        android:id="@+id/navigation_qa"
        android:icon="@drawable/ic_launcher_foreground"
        android:title="@string/q_a" />

    <item
        android:id="@+id/navigation_system"
        android:icon="@drawable/ic_launcher_foreground"
        android:title="@string/system" />

    <item
        android:id="@+id/navigation_mine"
        android:icon="@drawable/ic_launcher_foreground"
        android:title="@string/mine" />
</menu>
將Navigation與BottomNavigationView關(guān)聯(lián)
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        navView.setupWithNavController(navHostFragment.findNavController())
通過NavController 管理fragment之間的跳轉(zhuǎn)
findNavController().navigate(R.id.action_to_artical)

navigate方法傳入配置的某個action來進行跳轉(zhuǎn)。

跳轉(zhuǎn)傳遞參數(shù)
            var args = Bundle()
            args.putString("params", "params")
            Navigation.findNavController(btnHome).navigate(R.id.fragment_home_to_fragment_msg, args)
目標(biāo)頁接收參數(shù):
var params = arguments?.getString("params")
導(dǎo)航文件拆分

如果項目越來越大小作,頁面越來越多亭姥,所有的都放在一個文件中會非常的臃腫,當(dāng)Action非常復(fù)雜的時候會非常的混亂顾稀。那么可創(chuàng)建多個navigation.xml進行導(dǎo)航达罗。

Deeplink導(dǎo)航

Navigation也能通過Deeplink進行跳轉(zhuǎn)。如下:

findNavController().navigate(Uri.parse("schema://webview.fragment"))

參考:
https://blog.csdn.net/JMW1407/article/details/125714708
https://blog.csdn.net/lcl130/article/details/108422026

Github代碼地址:

https://github.com/running-libo/MviFlowHilt/tree/master

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末静秆,一起剝皮案震驚了整個濱河市粮揉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌抚笔,老刑警劉巖扶认,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異殊橙,居然都是意外死亡辐宾,警方通過查閱死者的電腦和手機狱从,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叠纹,“玉大人季研,你說我怎么就攤上這事∮欤” “怎么了与涡?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長冒窍。 經(jīng)常有香客問我递沪,道長豺鼻,這世上最難降的妖魔是什么综液? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮儒飒,結(jié)果婚禮上谬莹,老公的妹妹穿的比我還像新娘。我一直安慰自己桩了,他們只是感情好附帽,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著井誉,像睡著了一般蕉扮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颗圣,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天喳钟,我揣著相機與錄音,去河邊找鬼在岂。 笑死奔则,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蔽午。 我是一名探鬼主播易茬,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼及老!你這毒婦竟也來了抽莱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤骄恶,失蹤者是張志新(化名)和其女友劉穎食铐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叠蝇,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡璃岳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年年缎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铃慷。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡单芜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出犁柜,到底是詐尸還是另有隱情洲鸠,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布馋缅,位于F島的核電站扒腕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏萤悴。R本人自食惡果不足惜瘾腰,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望覆履。 院中可真熱鬧蹋盆,春花似錦、人聲如沸硝全。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伟众。三九已至析藕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凳厢,已是汗流浹背账胧。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留数初,地道東北人找爱。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像泡孩,于是被迫代替她去往敵國和親车摄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容