什麼是Navigation:
在Android開發當中,導航是指允許用戶再應用內進入和退出不同內容的交互組件。而我們通過 Android Jetpack的導航組件可以幫助我們實現導航功能。導航組件還能可能遵循既定的原則來保證用戶有一個良好的用戶體檢。
導航組件的構成:
1.Navigation graph(導航圖):
這是一個包含所有位置導航相關信息的XML資源文件。這裏包括應用程序當中的所有單獨的內容區域(被稱爲目標視圖),以及連接在應用程序當中各個“目標”的路徑。
2.NavHost:
一個用於展示導航圖當中目標視圖的空的容器。Navigation組件包含一個實現NavHostFragment的默認的NavHost,它是用來展示fragment的目的地。
3.NavController:
管理NavHost中的應用程序導航的對象。 當用戶在整個應用程序中移動時,NavController會協調NavHost中目標內容的交換。
當我們通過導航瀏覽我們的應用程序的時候,我們可以通知NavController我們要沿着導航圖當中的特定的路徑進行導航,或者直接導航到特定的目的地。接下來NavController可以在NavHost當中顯示出適當的目標視圖。
Navigatin組件的優點:
- 可以處理fragment的事務。
- 默認情況下可以正確的處理好各個事物之間前後的操作。
- 可以供標準化的過渡動畫資源。
- 實現和處理深度鏈接。
- 涵蓋了一些導航UI模式,比如只需要很少的額外工作就能實現抽屜導航和底部導航。
- Safe Args - 一種Gradle插件,可在目的地之間導航和傳遞數據時提供安全的數據類型。
使用
1.在mudle的gradle中添加依賴
dependencies {
implementation "android.arch.navigation:navigation-fragment:1.0.0-alpha02"
implementation "android.arch.navigation:navigation-ui:1.0.0-alpha02"
}
2.在 res 目錄上右鍵 new -> Android Resource Directory ,選擇 navigation
3.創建Navigation跳轉關係界面
在這裏同layout文件一樣,有兩種實現方式
- 一種是書寫xml標籤代碼來實現
- 另一種則是通過界面化添加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/main_navigation"
app:startDestination="@id/oneFragment">
<fragment
android:id="@+id/oneFragment"
android:name="com.example.pagingdemo.OneFragment"
android:label="fragment_one"
tools:layout="@layout/fragment_one" ></fragment>
<fragment
android:id="@+id/twoFragment"
android:name="com.example.pagingdemo.TwoFragment"
android:label="fragment_two"
tools:layout="@layout/fragment_two" >
<!--頁面跳轉傳值-->
<argument
android:name="test"
android:defaultValue="@string/dian"
app:argType="string"/>
<!--頁面跳轉的動作-->
<action
android:id="@+id/action_twoFragment_to_threeFragment"
app:destination="@id/threeFragment" />
</fragment>
<fragment
android:id="@+id/threeFragment"
android:name="com.example.pagingdemo.ThreeFragment"
android:label="fragment_three"
tools:layout="@layout/fragment_three" ></fragment>
</navigation>
看一下Navigation文件中的各個屬性
navigation標籤下的屬性:
- app:startDestination 默認的起始位置
fragment 標籤下的屬性:
- name: 這個屬性是你這個節點所對應的fragment(需要你導入指定的fragment文件路徑)
- label:一個標籤名稱,用於記錄這個節點的標籤信息
- :layout: 設置它後你可以在切換到Design模式後看到,視圖頁面的fragment的預覽圖
argument 有三個屬性 name、defaultValue 和 type:
- name 就是名字到時會生成這個名字的 set 和 get 方法,
- defaultValue 是默認值,
- type 就是數據類型,有以下幾種可以使用
4.設置fragment之間的過渡動畫
- 選中fragment之間跳轉的箭頭
- 在右側Animations中添加過渡動畫
此時便會在action標籤下補充添加動畫代碼,過渡動畫也就添加成功
5.通過Navigation將Activity與Fragment關聯起來:(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/main_fragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/main_navigation"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
我們注意一下fragment中相關的屬性:
-
name : 這是告知fragment需要使用navigation模式的關鍵屬性,另外它是固定死的.必需寫.
-
defaultNavHost : 這是實現物理按鍵(比如返回鍵),是按一下退出一個fragment 還是直接退出這個Activity的關鍵屬性
-
navGraph : 這是關聯前面我們創建navigition文件的屬性
需要注意的是 fragment 中的 android:name 後面配置的Fragment 不能和導航文件中的 app:startDestination 相同,否則會導致 Fragment創建兩次,所以這裏使用系統的默認實現,也就是 androidx.navigation.fragment.NavHostFragment,而在導航文件中 使 用的是 @id/main_fragment 最終導向的是 com.example.pagingdemo.OneFragment,其實系統的androidx.navigation.fragment.NavHostFragment 是一個空白Fragment ,它的 onCreateView 返回的是一個空白的佈局。只是用來實現導航的。
到此Navigation基本的使用就編輯完成了
6使用Navigation實現fragment之間跳轉與返回:
Navigiton實現fragment之間的跳轉是通過 NavController 對象,獲取NavController 對象有以下三種方法:
- NavHostFragment.findNavController(Fragment)
- Navigation.findNavController(Activity, @IdRes int viewId)
- Navigation.findNavController(View)
1).從第一個碎片跳轉到第二個碎片:
NavController 通過調用navigate方法進行跳轉,navgate()中可以傳入跳轉目標fragment的id,也可以傳入action的id.
例如:Navigation.findNavController(MainActivity.this,R.id.main_navigation).navigate(R.id.twoFragment);
2).從第二個碎片返回到第一個碎片:
NavController 通過調用popBackStack來實現返回
例如:Navigation.findNavController(MainActivity.this,R.id.main_navigation).popBackStack();