本文首發(fā)于個人博客澄暮,已授權郭霖轉載至其公眾號:guolin_blog
Navigation 是一個谷歌官方推出的一個用于 APP 內部便捷切換內容(Fragment 或 Activity)的庫。從而使得 APP 內的頁面跳轉更簡單晕窑。
我知道它的時候它的版本已經是 2.0.0 了啡氢,也是時候來學習一波了肴敛。
無論什么時候璃哟,學習的第一手資料不能缺了官方出品的 CodeLab缰猴。相信你产艾,看了 CodeLab 之后就能對 Navigation 有一個簡單的了解。本人也是對 CodeLab 學習之后才寫下了這篇博客滑绒,主要內容都能在 CodeLab 上找到闷堡。不過 CodeLab 里面是英文的講解,而且其中的代碼是使用 Kotlin 編寫的疑故,這篇博客是以 Java 代碼的方式進行的杠览。
還一件事情,Navigation 的原生支持是從 Android Studio 3.3 開始的纵势,3.2 版本的需要在設置面板的 Experimental 模塊中啟用 Navigation 編輯器踱阿。
圖片來自 CodeLab。
下面開始正題
Navigation Graph 和 NavHostFragment
首先钦铁,添加依賴软舌。
implementation 'androidx.navigation:navigation-fragment:2.0.0'
implementation 'androidx.navigation:navigation-ui:2.0.0'
之后,在 res 文件夾下創(chuàng)建類型為 navigation 的資源文件夾牛曹,Android Studio 會自動在這個文件夾下生產一個名為 navigation.xml 的文件佛点,這個文件的作用就是用于描述 Fragment 及相應的跳轉邏輯、動畫、參數等信息超营。這個文件也叫做 Navigation Graph鸳玩。
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/navigation">
</navigation>
默認的 Navigation Graph 文件就只有一個根節(jié)點,如果我們有更多的 Fragment演闭,添加進來不跟,會有不同的子節(jié)點,子節(jié)點代表的就是 Fragment船响,fragment 節(jié)點中描述關于 Fragment 的相關信息躬拢,并且在 fragment 節(jié)點中還可以其他子節(jié)點,比如见间,action聊闯、argument、deepLink米诉。他們分別用于表示 Fragment 的相關信息菱蔬。往后會講到的。現在我們現在創(chuàng)建一個 Fragment 史侣,就叫 RootFragment 好了拴泌。
<?xml version="1.0" encoding="utf-8"?>
<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=".fragment.RootFragment">
<TextView
android:layout_gravity="center"
android:gravity="center"
android:layout_width="match_parent"
android:textSize="24sp"
android:layout_height="match_parent"
android:text="Root Fragment"/>
</FrameLayout>
只是在頁面上顯示出這個 Fragment 的名字,Java 代碼中沒有做任何事情【鳎現在讓我們回到 Navigation Graph 中蚪腐,我們是初學者,不知道或者說不了解 Fragment 節(jié)點有哪些屬性可以去使用税朴,可以使用 Navigation Graph 的圖形化界面回季,剛才我們看了 Navigation Graph 的代碼,現在來看一下正林,圖形化編輯頁面泡一。
左邊區(qū)域:是已經添加進來的 Fragment 以及承載這些 Fragment 的頁面;
中間區(qū)域:Fragment 的跳轉示意圖觅廓;
右邊區(qū)域:是當前選中的 Fragment 的屬性展示區(qū)鼻忠;
頁面中間已經提示我們了,點擊那個圖標杈绸,添加一個目標帖蔓。試試看吧,從 Android Studio 展示出的列表中蝇棉,找到我們剛才創(chuàng)建的 RootFragment讨阻。這時,頁面已經發(fā)生了變化篡殷。我們剛才創(chuàng)建的 RootFragment 的樣子已經出現了,而且名稱前還有一個小圖標埋涧,這表示 RootFragment 是 Navigation 管理頁面的第一個頁面也是開始頁面板辽。
頁面右側出現了一些屬性奇瘦,我們暫時可以不用管,現在我只想先運行起來劲弦,看看效果耳标。不過在這之前,我們還需要改造一下邑跪,之前新建項目自動生成的 MainActivity次坡。先打開 activity_main.xml 的圖形化編輯頁面,然后在 Palette 類型列表中找到 NavHostFragment 并拖拽到頁面上画畅,此時會彈出一個框砸琅,讓你選擇 Navigation Graph,我們選擇剛才自動創(chuàng)建的文件即可轴踱。
Android Studio 的布局文件的拖拽症脂,不是太好用,需要手動切換到源代碼形式淫僻,簡單改動一下頁面代碼诱篷,我們讓這個 NavHostFrgament 組件填充滿整個容器即可。
最終的 activity_main.xml 的源文件如下:
<?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:navGraph="@navigation/navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
然后運行項目即可雳灵。這就是一個最簡單的使用 Navigation 的例子棕所,而且其中根本就沒什么難度。
好悯辙,現在我們來回過頭來看看琳省,剛剛我們都做什么。我們真正有效的內容是從把 RootFragment 添加到 Navigation Graph 中笑撞,我們去看一下岛啸,Navigation Graph 的源代碼。說不定能從那里發(fā)現點什么東西茴肥。
<?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/navigation"
app:startDestination="@id/rootFragment">
<fragment
android:id="@+id/rootFragment"
android:name="me.monster.blogtest.fragment.RootFragment"
android:label="fragment_root"
tools:layout="@layout/fragment_root" />
</navigation>
這個文件跟之前自動生成的沒什么區(qū)別坚踩,無非就是多了一個 fragment 節(jié)點,以及根節(jié)點上多了一個 startDestination 屬性瓤狐。難道就是因為這個屬性瞬铸?是的,沒錯础锐,在 Navigation 中我們使用 Destination(目標)來描述 Fragment 之間的跳轉關系嗓节。這里的 startDestination 代表的就是這個是 Navigation 整個頁面跳轉管理棧的最根級頁面。
再來看看那個添加到 MainActivity 頁面的 NavHostFragment 組件皆警。它其實就是一個布局文件中的 fragmen 組件拦宣,跟我們正常使用的沒什么不同,非要說不同,那就是其中的 name鸵隧、defaultNavHost 以及 navGraph 這三個屬性了绸罗。
name 屬性我們都知道,navGraph 屬性里面的值是剛才創(chuàng)建 Navigation Graph豆瘫,猜一下珊蟀,就是把 Navigation Graph 引用到了這個 NavHostFragment 中。那最后一個 defaultNavHost 屬性呢外驱?那就是攔截系統(tǒng)返回按鈕的點擊事件的育灸。
<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:navGraph="@navigation/navigation" />
NavController
單單一個 Fragment 沒啥意思,不好玩昵宇,這回我們再加一個頁面(SettingsFragment)磅崭。嘗試著從 RootFragment 頁面點擊按鈕切換到 SettingsFragment 頁面。然后在 SettingsFragment 頁面點擊按鈕返回到 RootFragment 頁面趟薄。
說是 SettingsFragment绽诚,里面就一個 Button 一個 TextView,布局代碼就不貼了杭煎。
Fragment 準備好了恩够,該往 Navigation Graph 里添加了,按照剛才添加 RootFragment 的方式再來一次羡铲,不過蜂桶,這次比上次多一步。選中 RootFragment也切,點擊 RootFragment 右邊的小圓點然后牽引到右側的 SettingsFragment扑媚。這樣他們兩個就建立一種關系。
來看一下源代碼吧雷恃。我們發(fā)現疆股,除了增加了一個 fragment 節(jié)點之外,原來的 RootFragment 的節(jié)點上還增加了一個子節(jié)點 action 倒槐。事實上旬痹,action 節(jié)點就是用來描述 Fragmen 之間的頁面跳轉的關系的,其中 destination 屬性的值就是目標 fragment 的 id讨越。
<fragment
android:id="@+id/rootFragment"
android:name="me.monster.blogtest.fragment.RootFragment"
android:label="fragment_root"
tools:layout="@layout/fragment_root" />
<!--上面是原來的代碼两残,下面是新代碼-->
<fragment
android:id="@+id/rootFragment"
android:name="me.monster.blogtest.fragment.RootFragment"
android:label="fragment_root"
tools:layout="@layout/fragment_root" >
<action
android:id="@+id/action_rootFragment_to_settingsFragment2"
app:destination="@id/settingsFragment" />
</fragment>
<fragment
android:id="@+id/settingsFragment"
android:name="me.monster.blogtest.fragment.SettingsFragment"
android:label="SettingsFragment" />
繼續(xù)往下,我們?yōu)?RootFragment 頁面綁定點擊事件把跨。
private void toSettings() {
btnToSettings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Navigation.findNavController(btnToSettings)
.navigate(R.id.action_rootFragment_to_settingsFragment);
}
});
}
這一看就知道了人弓,通過 Navigation 找到一個叫 NavController 的東西,然后執(zhí)行 navigate 方法着逐,這個方法里面?zhèn)鞯闹稻褪莿偛?RootFragment 子節(jié)點 action 的 id 的值崔赌。先運行一下看看效果意蛀。
- 親測點擊按鈕能跳轉到 SettingsFragment 頁面。下面的 Gif 動圖只是表示能從 RootFragment 到 SettingsFragment峰鄙,閃回到 RootFragment 頁面只是 Gif 的重新播放浸间。
- 如果你在 SettingsFragment 點擊系統(tǒng)的返回鍵太雨,是能返回到 RootFragment吟榴。這就是 MainActivity 中 NavHostFragment 組件的屬性
app:defaultNavHost="true"
起到的作用,有興趣的話囊扳,可以改成 false 然后再試一下效果吩翻。
現在,讓我們再次為 SettingsFragment 添加按鈕的點擊事件吧锥咸。
private void goBack() {
btnToRoot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Navigation.findNavController(btnToRoot)
.popBackStack();
}
});
}
和之前跳轉到這個頁面的方式差不多狭瞎,只是最后執(zhí)行的方法變成了 popBackStack
。
嗯搏予,挺好的熊锭,不過,我們有些時候需要在兩個 Fragment 之間做切換動畫雪侥,這個怎么辦碗殷?這個也不難,在Navigation Graph 中跳轉的 action 內增加屬性即可速缨。吶锌妻,這樣就行了,而且還可以用過 Java 代碼來實現旬牲。
<fragment
android:id="@+id/rootFragment"
android:name="me.monster.blogtest.fragment.RootFragment"
android:label="fragment_root"
tools:layout="@layout/fragment_root">
<action
android:id="@+id/action_rootFragment_to_settingsFragment"
app:destination="@id/settingsFragment"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
</fragment>
Java 代碼
Navigation.findNavController(btnToSettings)
.navigate(R.id.action_rootFragment_to_settingsFragment);
// 上面是原來的代碼仿粹,下面是新代碼
NavOptions options = new NavOptions.Builder()
.setEnterAnim(R.anim.slide_in_right)
.setExitAnim(R.anim.slide_out_left)
.setPopEnterAnim(R.anim.slide_in_left)
.setPopExitAnim(R.anim.slide_out_right)
.build();
Navigation.findNavController(btnToSettings)
.navigate(R.id.action_rootFragment_to_settingsFragment, null, options);
這里,我們調用了 navigate 這個方法原茅,其中第二個參數是 Bundle 類型吭历,我們填入了 null
,那如果正常填了值擂橘,Bundle 是不是就是傳遞到 SettingsFragment 了呢晌区?答案是肯定的。不過 Navigation 還有另一種方式來傳值—— Safe Args贝室。
Safe Args
為啥要用 Safe Args 呢契讲?
我也不知道為啥學,感覺如果單純?yōu)榱吮WC key 安全的話滑频,把 Bundle 里面的 key 抽取成常量值不也行嗎捡偏?不太懂為啥要通過這種形式來做,不過呢峡迷,老話說得好银伟,技多不壓身你虹。
Safe Args 是配合 Navigation 使用的一個 Gradle 插件。首先你得先去配置:
首先在你項目的根目錄的 build.gradle 文件中加上這些東西:
repositories {
google()
}
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.0.0"
}
然后還得在你的 app 或是 module 的目錄下的 build.gradle 文件夾加入:
apply plugin: "androidx.navigation.safeargs"
如果你想用 safe Args 生成的代碼時 Kotlin 的話彤避,還需要加入:
aapply plugin: "androidx.navigation.safeargs.kotlin"
最最最重要的一點是傅物,你要確認你的 build.properties 文件中有這么一行:
android.useAndroidX=true
當然了,如果你的項目本身就是用是 AndroidX 的依賴琉预,就不用去確認了董饰,肯定能通過的嘛。
現在我們就來從 RootFragmet 傳遞一個類型為 String 的備注名到 SettingsFragmen 吧圆米。還是先通過圖形化界面進行設置吧卒暂,選中 SettingsFragment,然后再右側屬性面板上找到 Argments 點擊旁邊的?娄帖。
彈出一個框也祠,我們填入一下信息,然后點擊 add近速。
完成之后的 Navigation Graph 中 SettingsFragment 節(jié)點的內容變了诈嘿。
<fragment
android:id="@+id/settingsFragment"
android:name="me.monster.blogtest.fragment.SettingsFragment"
android:label="SettingsFragment"/>
<!--上面是原來的代碼,下面是新代碼-->
<fragment
android:id="@+id/settingsFragment"
android:name="me.monster.blogtest.fragment.SettingsFragment"
android:label="SettingsFragment">
<argument
android:name="nickName"
android:defaultValue="未設置"
app:argType="string"
app:nullable="true" />
</fragment>
這個時候削葱,Gradle 會自動生成 SettingFragmentArgs 以及 RootFragmentDirections 這兩個類奖亚,在 generatedJava 這個文件夾下的包內。如果沒有自動生成的話佩耳,clean 一下或是 rebuild 項目都行遂蛀。
現在就能直接通過 setNickName 的形式來設置待傳遞的值了。
String nickName = "master";
RootFragmentDirections.ActionRootFragmentToSettingsFragment action =
RootFragmentDirections.actionRootFragmentToSettingsFragment().setNickName(nickName);
Navigation.findNavController(btnToSettings)
.navigate(action);
在 SettingsFragment 我們需要把值取出來干厚,然后顯示在屏幕上李滴。
String nickName = SettingsFragmentArgs.fromBundle(getArguments()).getNickName();
tvNickName.setText(nickName);
怎么樣,是不是很簡單蛮瞄,這比之前我們用 Bundle 傳值要方便的多啦所坯,而且再也不用擔心 Key 寫錯的問題了。真香挂捅。
好了芹助,Navigation 的基本學習就到這了,感覺真的挺不錯的闲先∽赐粒可以考慮用用了,不過現在好像主頁面都是四個或是五個 Tab 頁面伺糠,這用 Navigation 怎么實現呀蒙谓?Google 早就替我們想好了。
BottomNavigationView
來训桶,我們新建一個 Activity累驮,然后打開布局文件的圖形化工具頁面酣倾,用之前我們添加 NavHostFragment 組件的方式來添加一個 BottomNavigationView,然后讓這個組件位于整個頁面的底部谤专。頁面的其余部分全部都留給 NavHostFragment躁锡。因為我們又引入了一個新的 Fragment 管理棧,所以置侍,需要再次新建一個 Navigation Graph 文件 tab_navigation映之。
下面就是 activity_tab.xml 以及 tab_navigation.xml 的代碼。
<?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=".TabActivity">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nv_bottom_menu"
android:layout_width="match_parent"
android:layout_height="48dp"
app:itemHorizontalTranslationEnabled="false"
app:layout_constraintBottom_toBottomOf="parent" />
<fragment
android:id="@+id/fragment3"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/nv_bottom_menu"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/tab_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab_navigation">
</navigation>
接下來干什么呢墅垮?剛才我們創(chuàng)建是容器惕医,用于容納 Fragment 的,現在來創(chuàng)建三個 Fragment算色,這三個 Fragment 是用于填充進容器的內容。
分別是 FeedFragment螟够、TimerFragment灾梦、MineFragment。這三個 Fragment 我們還是分別顯示自己的名稱妓笙。布局文件里也就一個 TextView若河,Java 代碼中什么也不做,僅僅是用來顯示寞宫。
有了三個 Fragment萧福,我們現在去 tab_navigation 把這三個 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/tab_navigation"
app:startDestination="@id/feedFragment">
<fragment
android:id="@+id/feedFragment"
android:name="me.monster.blogtest.tab.FeedFragment"
android:label="fragment_feed"
tools:layout="@layout/fragment_feed" />
<fragment
android:id="@+id/timerFragment"
android:name="me.monster.blogtest.tab.TimerFragment"
android:label="fragment_timer"
tools:layout="@layout/fragment_timer" />
<fragment
android:id="@+id/mineFragment"
android:name="me.monster.blogtest.tab.MineFragment"
android:label="fragment_mine"
tools:layout="@layout/fragment_mine" />
</navigation>
現在辈赋,我們容器有了鲫忍,內容有了,只差一個媒介钥屈,把它們進行關聯了悟民。打開 activity_tab 的圖形化界面,在左側有一些屬性篷就,其中有一個屬性是 menu射亏。menu?就是那個經常用于頁面右上角的 menu竭业?它怎么會出現在這邊智润?點擊 menu 行最右邊的按鈕。
彈出一個對話框未辆,好像和一開始創(chuàng)建 NavHostFragment 是一樣的窟绷,不同的是,當時有待選擇的 Navigation Graph 文件鼎姐,現在我們沒有 menu 文件钾麸,那就創(chuàng)建一個吧更振。
現在我們也有了 menu 文件。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/feedFragment"
android:icon="@drawable/ic_tab_feed"
android:title="Feed" />
<item
android:id="@+id/timerFragment"
android:icon="@drawable/ic_tab_timer"
android:title="Timer" />
<item
android:id="@+id/mineFragment"
android:icon="@drawable/ic_tab_mine"
android:title="Mine" />
</menu>
現在再回去看 tab_activity.xml 發(fā)現 preview 已經變成了這樣的饭尝。Cool
難道 Menu 就是那個把內容 (Fragment) 與容器 (NavHostFragment) 進行建立關系的媒介肯腕?是也不是,有那么一點關系钥平,不過不太準確实撒。還記得之前我們用與 RootFragment 和 SettingsFragment 進行切換頁面的方式嗎?一個是前進到下一個頁面涉瘾,一個是返回上一個頁面知态,雖然最終的行為不同,但是它們都使用到了一個叫 NavController 的類立叛,這個類實際上就是實現在 Fragment 之間進行跳轉的類负敏。
Navigation.findNavController(btnToSettings).navigate(action);
Navigation.findNavController(btnToRoot).popBackStack();
那我們是不是可以通過 Navigation Controller 并結合底部導航菜單的點擊事件來對 Fragment 進行控制,從而實現 Fragment 之間的切換秘蛇?是這樣的其做,沒錯,不過 Google 幫助我們完成了很多復雜的事情赁还,我們只需要在 TabActivity 中添加下面這些代碼即可妖泄。
private void setUpNavBottom() {
NavHostFragment hostFragment = (NavHostFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment3);
BottomNavigationView navMenu = findViewById(R.id.nv_bottom_menu);
if (hostFragment != null) {
NavController navController = hostFragment.getNavController();
NavigationUI.setupWithNavController(navMenu, navController);
}
}
第一行,findFragmentById 里填寫的 id 就是我們在 tab_activity.xml 中 name 屬性是 NavHostFragment 節(jié)點的 id艘策。
然后再通過 NavigationUI.setupWithNavController()
將二者進行想管理蹈胡,這樣只要我們點擊底部導航菜單就是自動實現 Fragment 的之間的切換,完全不需要開發(fā)者自己去寫那么控制邏輯朋蔫。事實上罚渐,NavigationUI.setupWithNavController()
這個方法有很多重載方法,不僅僅只是用在 BottomNavigationView斑举,還有 NavigationView 等搅轿,在這里就不一一介紹了感興趣的可以去試試。現在來看看效果富玷。
DeepLink
來來來璧坟,回顧一下剛才我們介紹的 Navigation Graph,它就是用于描述 Fragment 或者說用于描述內容信息的赎懦,剛才我們嘗試了子節(jié)點 Fragment 的 action(頁面跳轉)與 arguments(Bundle 傳值)節(jié)點雀鹃,其實他還有一個子節(jié)點 deepLink。
不知道励两,你有沒有遇到那種情況黎茎,朋友在微信上分享你一個連接,你一點開当悔,頁面上提示你使用微信的在瀏覽器打開傅瞻,你在一點開發(fā)現踢代,發(fā)現跳轉到了一個應用的頁面上去了。這種跳轉方式在 Navigation 這個導航框架內叫做 deepLink嗅骄。讓我們來實現一下吧胳挎。
我們需要準備一個 Fragment,就叫 DeepLinkFragment 好了溺森,這個頁面我們跟之前的 Fragment 一樣只顯示 DeepLinkFragment 這個文字好了慕爬。layout 布局文件及 Java 代碼就不貼了。現在再來看 Navigation Graph 中怎么寫屏积。
fragment
android:id="@+id/deepLinkFragment"
android:name="me.monster.blogtest.fragment.DeepLinkFragment"
android:label="fragment_deep"
tools:layout="@layout/fragment_deep" >
<deepLink
android:id="@+id/deepLink"
app:uri="www.example.com/{myarg}" />
</fragment>
是的医窿,你沒有看錯,在 Navigation Graph 中就多了這么點東西炊林,然后記得一定要記得在 manifest 的承載 DeepLinkFragment 的 Activity 節(jié)點內引入你的 Navigation Graph姥卢。
- 那里填的 url 后面大括號包裹著的是傳入 DeepLinkFragment 的值,
myarg
是 key铛铁,通過 Bundle 進行傳遞隔显;- 我在寫這篇博客的時候,有兩個 Navigation Graph 文件饵逐,一個是用于 RootFragment 與 SettingsFragment 進行跳轉的 navigation.xml,一個是用于底部導航菜單欄的 tab_navigation.xml彪标,我把 DeepLinkFragment 放在了 navigation.xml 中倍权,所以下面的值是 @navigation/navigation。
<nav-graph android:value="@navigation/navigation" />
來試一下捞烟,看看效果吧薄声。
好了,我們整個 Navigation 的學習到這里也告一段落了题画,結束之前讓我們用一幅圖來回顧一下 Navigation默辨。
本文首發(fā)于個人博客,文中全部源代碼已上傳至 GitHub苍息,喜歡的麻煩點個??缩幸。
本文封面圖:Photo by Joseph Barrientos on Unsplash