close

Navigation 是 Jetpack 中的一個頁面轉換元件

簡單的來說,是用來取代 FragmentTransaction 之類的操作

Navigation 的出現,讓生態更偏向「一個APP, 一個 Activity」這一派系

也就是一個 Activity 用多個 Fragment 來做 UI 呈現

 

使用 Navigation 能更方便的管理各 Fragment 之間的問題

減少傳遞值所造成的 run time crash

而且視覺化的 Navigation graph 也讓頁面間的關係更加清楚

 

那我們就來用用看 Navigation 吧

注意:這功能只有 Android Studio 3.3 以上才能使用喔

首先 implementation 

dependencies {
    def nav_version = "2.1.0"

    // Java
    implementation "androidx.navigation:navigation-fragment:$nav_version"
    implementation "androidx.navigation:navigation-ui:$nav_version"

    // Kotlin
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}

Java 與 Kotlin 需要 implementation 是分開的

請各位自行選擇使用的語言

 

Gradle sync 之後我們可以在 res 右鍵來新增 resource file 如圖

 

打上名字,並選擇 Type 為 Navigation

建立的檔案路徑會是 res/navigation/xxx.xml

 

建好之後,我們就能以 GUI 直接編輯囉

 

可以看到 launchFragment 有一個房子的圖標

那是代表整個 navigation 的開頭

想增加 Fragment or Activity 的話,點上方有綠色 + 號的圖示

而若想要讓跳轉頁面的話,將 launchFragment 右邊的圓點拖過去即可

這麼一來,我們就可以很清楚明白的看出各頁面的關係

接下來,我們來看看 generate 出來的 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/main_nav"
    app:startDestination="@+id/launchFragment">

    <fragment
        android:id="@+id/launchFragment"
        android:name=
        "com.iStaging.vrcameraphone.enterprise.ui.LaunchFragment"
        android:label="fragment_launch"
        tools:layout="@layout/fragment_launch">
        <action
            android:id=
            "@+id/action_launchFragment_to_mainFragment"
            app:destination="@id/mainFragment" />
    </fragment>
    <fragment
        android:id="@+id/mainFragment"
        android:name=
        "com.iStaging.vrcameraphone.enterprise.ui.main.MainFragment"
        android:label="MainFragment" />
</navigation>

要注意的是 android:id="@+id/action_launchFragment_to_mainFragment" 

這個 id 會是我們等一下跳頁時需要的值之一

 

下一步,把我們的 navigation 連接到 MainActivity 的 layout.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 
    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/container"
        android:name=
        "androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/main_nav" />
</FrameLayout>

主要的設定有三項

1、android:name="androidx.navigation.fragment.NavHostFragment"

用來宣告實現此 Fragment 為 NavHostFragment
 

2、app:defaultNavHost="true"

true 的話,會去攔截 system back button,讓頁面返回上一層

不會退出 Activity,而上一層可以是 Fragment or Activity
 

3、app:navGraph="@navigation/main_nav"

將 layout.xml 與 navigation 連接起來的關鍵參數

 

將上面的步驟設定完成之後

我們就可以開始使用了

Kotlin:

Java:

利用 NavController 去做轉頁的動作

當然也可以添加動畫、傳遞參數、Bundle

code 如下:

switchFragment(R.id.action_launchFragment_to_mainFragment)

fun switchFragment(@IdRes actionIdRes: Int) {
    findNavController(R.id.container).navigate(actionIdRes, Bundle())
}

 

動畫在 GUI 就可以設定

選取要設定動畫的那筆箭頭

然後在 Animations 加入要用的 動畫 resource xml 即可

大致就是這樣了

Navigation 的出現讓管理 Fragment 簡化了許多

下一篇會講怎麼用 safe args 來在 Fragment 之前傳遞資料

點我看下一篇 Android Kotlin/Java Jetpack Navigation (二) Safe Args 介紹、入門教學 example、sample code 實作範例』Willy's Fish教學筆記

 

 

資料來源:

https://developer.android.com/guide/navigation/navigation-getting-started#kotlin

 

 

 

 

 

 

 

 

 

arrow
arrow

    顏澤偉 發表在 痞客邦 留言(0) 人氣()