iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Mobile Development

Andoroid - Kotlin筆記 (新)系列 第 12

[Day12] Android - Kotlin筆記:JetPack - Fragments在Navigation中的參數傳遞(Safe Args)

  • 分享至 

  • xImage
  •  

Fragments在Navigation中的參數傳遞 - SafeArgs

繼上篇我們得知如何運用NavigationFragment中做頁面切換。
而今天要講的是Safe Args
他的作用是在Fragment中頁面切換時,傳遞參數(Arguments)。


首先要在app的build.gradle加入:

dependencies {
    implementation("androidx.navigation:navigation-runtime-ktx:2.3.5")
    implementation("androidx.navigation:navigation-fragment-ktx:2.3.5")
    implementation("androidx.navigation:navigation-ui-ktx:2.3.5")
}

module層的build.gradle

apply plugin: "androidx.navigation.safeargs.kotlin"

我們將昨天的navigation.xml打開,會看到所有頁面。

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/aFragment"
    android:id="@+id/nav_graph">
    <fragment
        android:id="@+id/aFragment"
        android:name="com.example.cashdog.cashdog.AFragment"
        android:label="@string/label_blank"
        tools:layout="@layout/fragment_blank" >
        <action
            android:id="@+id/action_aFragment_to_bFragment"
            app:destination="@id/bFragment" />
    </fragment>
    <fragment
        android:id="@+id/bFragment"
        android:name="com.example.cashdog.cashdog.BFragment"
        android:label="@string/label_blank_2"
        tools:layout="@layout/fragment_blank_fragment2" />
</navigation>

假設我們要從AFragment傳遞參至BFragment
會在BFragment底下加入:

<argument
        android:name="userName"
        app:argType="string" 
        app:nullable="false"/>
  • android:name: 可以視為argument的id
  • app:nullable: AFragment頁面轉到BFragment時,是否為必傳值。false為必填,true可不填。
  • app:argType: argument的型態。

app:argType能選擇的類型有:

加入navigation.xml中,會像這樣:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/aFragment"
    android:id="@+id/nav_graph">
    <fragment
        android:id="@+id/aFragment"
        android:name="com.example.cashdog.cashdog.AFragment"
        android:label="@string/label_blank"
        tools:layout="@layout/fragment_blank" >
        <action
            android:id="@+id/action_aFragment_to_bFragment"
            app:destination="@id/bFragment" />
    </fragment>
    <fragment
        android:id="@+id/bFragment"
        android:name="com.example.cashdog.cashdog.BFragment"
        android:label="@string/label_blank_2"
        tools:layout="@layout/fragment_blank_fragment2">
        <argument
            android:name="userName"
            app:argType="string" 
            app:nullable="false"/>
    </fragment>
</navigation>

傳遞args的方式

直接將要傳遞的參數寫入actionAFragmentToBFragment(argument)中,

val action = AFragmentDirections.actionAFragmentToBFragment(userName)
class AFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        view.findViewById<Button>(R.id.next)
            .setOnClickListener {
                val action = AFragmentDirections.actionAFragmentToBFragment(userName)
                view.findNavController().navigate(action)
            }
    }
}

取得args的方式 - by navArgs

BFragment中取得傳遞過來的argument包裹:

val args by navArgs<BFragmentArgs>()

直接獲取argument中的內容方式如下:

val userName = args.userName
class BFragment : Fragment() {

    private val args by navArgs<BFragmentArgs>()

    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val userName = args.userName
    
     }
     ...

}

比起以前的寫法相較快很多:

val userName = arguments?.getString("userName") ?: ""

參考:


上一篇
[Day11] Android - Kotlin筆記:JetPack - Navigation (Fragment間的頁面跳轉)
下一篇
[Day13] Android - Kotlin筆記:Parcelable & Serializable 與 SafeArgs的傳遞
系列文
Andoroid - Kotlin筆記 (新)18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言