咱們瞭解了Navigation以後,就不得不提Navigation Editor。咱們能夠經過Android Studio的 Navigation Editor去編輯和瀏覽咱們的Navigation graph(導航圖)android
請注意這裏必需要求咱們的的Android Studio版本在3.3或者以上版本git
目前也有不少文章介紹Navigation以及Navigation Editor可是更多的是介紹Android Studio3.3以前版本的,本篇文章着重介紹的是Android Studio3.3及以上版本,有不少不一樣之處。如需應用如下內容請先升級Android Studio至3.3或者以上版本。github
在Module下面的build.gradle當中bash
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
}
複製代碼
導航是發生在應用的目標示圖之間——用戶能夠導航到應用當中的任何的位置。將這些目標視圖經過操做來鏈接起來。
導航圖是包括全部的目標視圖和操做的一個資源文件,這個導航圖標表明瞭咱們應用的全部的導航路徑圖。app
若是咱們是第一次建立導航圖,Android Studio會在res文件夾下面建立一個navigation 的資源文件目錄,這個目錄當中就包含了咱們剛纔建立的資源文件。如圖:編輯器
點擊打開剛纔建立的Navigation的xml文件,而後選擇Design。 咱們能夠看到Navigation Editor控制面板自左向右有三部分如圖: ide
控制面板分紅了三部分分別是:點擊Text咱們能夠看到XML文件gradle
<?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>
元素做爲子元素。動畫
一個主導航必須由NavHost派生而來,導航組件默認經過NavHost來實現,NavHostFragment來處理目標fragment直接的切換。ui
在咱們應用程序的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而後找到已經存在目標視圖,選擇便可。
如圖:
目標視圖咱們已經建立完成了,接下來咱們就開始鏈接各個目標視圖了。固然,咱們鏈接目標視圖就是經過Navigation Editor來完成。
<?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來講:
對於Kotlin來講:
下面咱們就看一下在咱們要實現的效果:
下面咱們看一下實現代碼,在OneFragment當中
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)
}
}
}
複製代碼
只須要添加就能夠實現跳轉功能,是否是很方便?
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。 兩種方法均可以實現跳轉,可是我更建議用第一種,由於第一種能夠配合着過渡的動畫使用。
咱們常見的一種邏輯以下: 有三個目標視圖分別是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"/>
複製代碼
當我嘗試寫這篇文章,並認真看過了官方文檔,本身也實踐以後發現Navigation以及Navigation Editor真的很是實用!在代碼當中,咱們不用寫不少的Activity。寫一個Activity嵌套多個Fragment就能夠完成,固然這也是谷歌一直推崇的一種方式。那麼不一樣的Fragment之間的跳轉,可能就是擺在咱們面前的一大難題,常常會有這樣會那樣的問題,同時邏輯不是很清晰而且須要大量的代碼用來實現。可是有了Navigation和Navigation Editor以後就有效的解決了這一問題!