天天看點

Android JetPack 之 Navigation

Navigation 可以更加友善的使用 Fragment,使用過程非常簡單,下面看一下使用方法

1,導入依賴

implementation 'android.arch.navigation:navigation-fragment:1.0.0'
    implementation 'android.arch.navigation:navigation-ui:1.0.0'
    androidTestImplementation 'android.arch.navigation:navigation-testing:1.0.0-alpha08'
           

2,在Res 目錄下 建立 navigation 檔案夾,然後建立 nav_graph.xml

Android JetPack 之 Navigation

3,在這個xml 檔案中 選擇自己的 fragment

Android JetPack 之 Navigation

​ 需要指定從那個 fragment 開始的話就直接 選中某個視圖 然後右擊 點選 Set as Start Destination 這個項目就可以将這個設定為 最開始的fragment,然後通過連線的方式确定他啟動的是哪一個fragment

4,在 Activity 中引用

​ 有兩種方式進行引用,修改 Activity 的布局如下所示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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"
    android:orientation="vertical"
    tools:context=".mvp.base.BaseActivity">


    <!-- name 是NavHostFragment,他實作了NavHost,這是一個用于放置管理的 destination 的空視圖 -->
    <!-- defaultNavHost 表示NavHostFragment 可以攔截處理傳回鍵  -->
    <!-- navGraph 用于将這個 NavHostFragment 和 nav_graph.xml 關聯起來 -->
    <fragment
        android:id="@+id/nav_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph"/>

</androidx.appcompat.widget.LinearLayoutCompat>
           

​ 通過上面這種方式就可以 顯示第一個fragment 了。

​ 還有一種方式,如下:

<androidx.appcompat.widget.LinearLayoutCompat 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"
    android:orientation="vertical"
    tools:context=".mvp.base.BaseActivity">

    <FrameLayout
        android:id="@+id/frame_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
</androidx.appcompat.widget.LinearLayoutCompat>
           

​ 還需要在代碼中進行如下修改:

//找到xml 檔案
        NavHostFragment navHost = NavHostFragment.create(R.navigation.nav_graph);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.frame_layout,navHost)
                // 相等于 xml 中的 app:defaultNavHost="true"
                .setPrimaryNavigationFragment(navHost)
                .commit();
           

​ 即可完成加載

5,碎片之間的跳轉 和 回退棧

​ 在 nav_graph.xml 中将 fragment 連接配接好以後 就可以使用 Navigation 自帶的方法進行跳轉了,并且在跳轉的使用可以在nav_graph.xml 中設定跳轉的動畫。fragment 直接跳轉的方法 如下 :

// id 為nav_graph.xml 中 fragment 内 action 的id ,就是需要跳轉掉指定fragment的 id

fragment基本跳轉	A->B
Navigation.findNavController(rootView).navigate(id);

fragment 攜帶資料跳轉-Bundle   A->B
Navigation.findNavController(rootView).navigate(id, bundle);

跳轉方法,多級跳轉     A->B->C,C->A,避免Navigation 跳轉後重新執行生命周期方法
注意:這裡的id 為 需要回退到指定fragment的 id,并非action,不需要再 xml 中進行連線。
第二個參數 為false 表示 退棧不包括指定的id,否則會将 id 的那個fragment 也退掉
avigation.findNavController(rootView).popBackStack(id, false); //如果退棧一次就傳回 true

退棧方法
Navigation.findNavController(rootView).navigateUp();

           

6,生命周期

​ 通過 Navigation 進行跳轉後,原來 fragment 的生命周期會走到那一步呢?如下:

​ A —> B

​ 從 A 到 B ,則A的生命周期執行到 onDestroyView() ,這個方法的作用就是銷毀 fragment 的有關視圖 但是依然可以通過 onCreateView() 方法進行重寫建立視圖。

​ 在跳到 B 後,如果點選了 傳回,則 A 就會通過 onCreateView() 重新建立視圖。這時 B 就會 執行 onDestory()。

有關視圖 但是依然可以通過 onCreateView() 方法進行重寫建立視圖。

​ 在跳到 B 後,如果點選了 傳回,則 A 就會通過 onCreateView() 重新建立視圖。這時 B 就會 執行 onDestory()。

以上就是 Navigation 的用法,是不是非常簡單呢?