繼上篇我們得知如何運用Navigation
在Fragment
中做頁面切換。
而今天要講的是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
的idapp: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") ?: ""
參考: