上一篇文章我們介紹了谷歌官方組件NavigationNavigation(一)谷歌官方組件Navigation你真的了解嗎,接下來我們來探究一下如何使用。
Navigation Editor
我們了解了Navigation之后,就不得不提Navigation Editor。我們可以通過Android Studio的 Navigation Editor去編輯和瀏覽我們的Navigation graph(導航圖)
請注意這里必須要求我們的的Android Studio版本在3.3或者以上版本
目前也有很多文章介紹Navigation以及Navigation Editor但是更多的是介紹Android Studio3.3之前版本的,本篇文章著重介紹的是Android Studio3.3及以上版本,有很多不同之處。如需應用以下內容請先升級Android Studio至3.3或者以上版本。
開始使用Navigation Editor
1.環(huán)境配置
在Module下面的build.gradle當中
dependencies {
def nav_version = "1.0.0"
implementation "android.arch.navigation:navigation-fragment:$nav_version" // use -ktx for Kotlin
implementation "android.arch.navigation:navigation-ui:$nav_version" // use -ktx for Kotlin
}
創(chuàng)建導航圖
導航是發(fā)生在應用的目標示圖之間——用戶可以導航到應用當中的任何的位置。將這些目標視圖通過操作來連接起來。
導航圖是包括所有的目標視圖和操作的一個資源文件,這個導航圖標代表了我們應用的所有的導航路徑圖。
創(chuàng)建導航圖需要以下幾個步驟:
- 在Android Studio的主界面,在res目錄的文件夾下面,選擇New > Android Resource File然后我們就可以看到 New Resource File對話框。如下圖:
-
在File name這一欄當中輸入名稱,比如“nav_graph”。
-
在Resource type下拉列表然后選擇Navigation,點擊ok就可以了。
如果我們是第一次創(chuàng)建導航圖,Android Studio會在res文件夾下面創(chuàng)建一個navigation 的資源文件目錄,這個目錄當中就包含了我們剛才創(chuàng)建的資源文件。如圖:
打開Navigation Editor控制面板
點擊打開剛才創(chuàng)建的Navigation的xml文件,然后選擇Design。
我們可以看到Navigation Editor控制面板自左向右有三部分如圖:

控制面板分成了三部分分別是:
- Destinations panel(目標面板):列出當前導航的主機以及當前圖解編輯器當中的所有目的地。
- Graph Editor(圖解編輯器): 這里包含了導航圖的。
- Attributes(屬性):顯示導航圖中當前所選項的屬性。
點擊Text我們可以看到XML文件
<?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">
</navigation>
這里的</navigation>是導航圖的根元素,當我們要在圖標當中添加目標視圖和連接動作的時候,我們可以使用<destination>和<action>元素作為子元素。
在activity當中添加NavHost
一個主導航必須由NavHost派生而來,導航組件默認通過NavHost來實現,NavHostFragment來處理目標fragment直接的切換。
在XML文件當中添加NavHostFragment
在我們應用程序的main activity當中添加NavHostFragment
這里的添加有兩種方式
1. 復制下面代碼到xml的代碼文件當中
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true"
/>
** 2. 在design下面控制面板選擇**
位置如圖:

然后我們直接拖NavHostFragment 的視圖到我們的activity文件當中
在導航視圖當中添加目標視圖
這里總共有三種不同的方式可以在我們的導航視圖當中添加目標視圖
添加已經存在的目標視圖
如果我們想把已經存在的目標視圖想要添加在導航圖當中,我們只需要點擊New Destination然后找到已經存在目標視圖,選擇即可。
如圖:

創(chuàng)建新的目標視圖
-
在導航編輯器當中,點擊New Destination然后再選擇Create new destination 如圖:
-
然后彈出了New Android Component對話框,然后我們可以創(chuàng)建fragment。 如圖:
填寫完信息之后,我們就可以看到界面上出現了我們剛才創(chuàng)建的目標視圖
如圖:
-
創(chuàng)建占位目標視圖
我們可以通過占位視圖來表示未實現的目標視圖。 如圖:
連接目標視圖
目標視圖我們已經創(chuàng)建完成了,接下來我們就開始連接各個目標視圖了。當然,我們連接目標視圖就是通過Navigation Editor來完成。
-
在Navigation Editor當中打開Design 選項卡,然后我們可以看到右邊有個小圓點,這個就是我們想要的導航起點。 如圖:
-
然后拖拽鼠標,然后連接到了我們想要鏈接的目標視圖。之后我們就可以看到一個線的箭頭如圖:
這個就表示我們把兩個目標視圖連接了。
-
點擊這條連接的線,我們可以看到高亮了,而這條線代表的就是我們之前說的Action(行為)我們可以看到右側有相關屬性。 如圖:
- 點擊Text選項,我們可以看到XML文件代碼,其中相關屬性已經完成,如下
<?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/oneFragment">
<fragment android:id="@+id/oneFragment" android:name="demo.rlv.cehome.com.navigationcomponents.OneFragment"
android:label="fragment_one" tools:layout="@layout/fragment_one">
<action android:id="@+id/action_oneFragment_to_twoFragment" app:destination="@id/twoFragment"/>
</fragment>
<fragment android:id="@+id/twoFragment" android:name="demo.rlv.cehome.com.navigationcomponents.TwoFragment"
android:label="fragment_two" tools:layout="@layout/fragment_two"/>
</navigation>
導航到目標視圖
導航到目標視圖,我們需要用到NavController,它是用于管理NavHost中的應用程序導航的對象。 每個NavHost都有自己的相應NavController。
NavController有以下幾種獲取方式:
對于Java來說:
- NavHostFragment.findNavController(Fragment)
- Navigation.findNavController(Activity, @IdRes int viewId)
- Navigation.findNavController(View)
對于Kotlin來說:
- Fragment.findNavController()
- View.findNavController()
-
Activity.findNavController(viewId: Int)
下面我們就看一下在我們要實現的效果:
下面我們看一下實現代碼,在OneFragment當中
verride fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
view?.findViewById<Button>(R.id.button_one)?.setOnClickListener {
view?.let { Navigation.findNavController(it).navigate(R.id.twoFragment)
}
}
}
只需要添加就可以實現跳轉功能,是不是很方便?
Navigation.findNavController(it).navigate(R.id.twoFragment)
對于Button控件來說,還有另一種實現跳轉的方法
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// view?.findViewById<Button>(R.id.button_one)?.setOnClickListener {
// view?.let { Navigation.findNavController(it).navigate(R.id.twoFragment)
// }
// }
button_one.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.twoFragment, null))
}
兩種跳轉分別是傳入nav_graph.xml當中的action id和resource id。
兩種方法都可以實現跳轉,但是我更建議用第一種,因為第一種可以配合著過渡的動畫使用。
popUpTo and popUpToInclusive
我們常見的一種邏輯如下:
有三個目標視圖分別是A、B、C,有A到B,B到C,然后C到A。

可以看到當我們倒C之后,后臺堆棧當中包括A、B、C單個實例。當我們通過
popUpTo A回到A的時候,意味著我們從堆棧當中把B和C刪除了。當我們使用app:popUpToInclusive =“true”的時候,我們還會把A彈出堆棧并有效的清除它。如果我們沒有使用app:popUpToInclusive =“true”那么也意味著我們的堆棧當中包含兩個A的實例。實現代碼如下:
<action
android:id="@+id/action_c_to_a"
app:destination="@id/a"
app:popUpTo="@+id/a"
app:popUpToInclusive="true"/>
最后
當我嘗試寫這篇文章,并認真看過了官方文檔,自己也實踐之后發(fā)現Navigation以及Navigation Editor真的非常實用!在代碼當中,我們不用寫很多的Activity。寫一個Activity嵌套多個Fragment就可以完成,當然這也是谷歌一直推崇的一種方式。那么不同的Fragment之間的跳轉,可能就是擺在我們面前的一大難題,經常會有這樣會那樣的問題,同時邏輯不是很清晰并且需要大量的代碼用來實現。但是有了Navigation和Navigation Editor之后就有效的解決了這一問題!
文末送福利啦!
為此我整理了一些以往自己學習的視頻資料,如果有需要借鑒學習的開發(fā)者可以聯系我,免費獲取共同進步(Flutter丶Glide丶OPencv丶EventBus丶自定義View丶數據庫框架設計丶插件化組件化丶Binder等都有對應的視頻教學以及一些面試題)免費分享給大家。
(包括Java在Android開發(fā)中應用、APP框架知識體系、高級UI、全方位性能調優(yōu),NDK開發(fā),音視頻技術,人工智能技術,跨平臺技術等技術資料),希望能幫助到大家, 也節(jié)省大家在網上搜索資料的時間來學習。
資料領取方式:點擊鏈接加入群聊【Android開發(fā)交流】:https://jq.qq.com/?_wv=1027&k=57fcAxd,找群管理免費領取。備注一下簡書看到的來領取資料就可以了!












