Navigation uses the safe args plugin to pass parameters
1. Use configuration
Compared with the traditional way of passing parameters, afe args has the advantage of safe parameter types, and with the official support of Google, it is very convenient to pass parameters.
1. 根build.gradle
Add the plugin under the project
buildscript {
ext.kotlin_version = "1.3.72"
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.4"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.5.0"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
2, and then app的build.gradle
referenced in'androidx.navigation.safeargs.kotlin'
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'androidx.navigation.safeargs.kotlin'
}
3. After adding the plug-in, return to nav_graph, switch to design mode, and add the parameters that need to be received to the target page
Here you need to pass parameters when FragmentA jumps to FragmentB, so set parameters for FragmentB, click FragmentB, click + on the right side of Arguments on the right panel, enter the key value of the parameter, specify the parameter type and default value, and you can quickly add parameters
4. After adding, rebuild
click on the project, safeArgs will automatically generate some codes, /build/generated/source/navigation-args
you can see in the directory that
safeArgs will generate corresponding classes according to the fragment tag in nav_graph,
- The action tag will be
“类名+Directions”
named after, - The argument tag will be
“类名+Args”
named after .
After using safeArgs, pass parameters like this
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tv.setOnClickListener {
val navController = Navigation.findNavController(it)
//通过safeArgs传递参数
val navDestination = FragmentADirections.actionFragmentAToFragmentB2("test")
navController.navigate(navDestination)
// 普通方式传递参数
// val bundle = Bundle()
// bundle.putString("key", "test")
// navController.navigate(R.id.action_fragmentA_to_fragmentB2, bundle)
}
}
The receiving parameters are like this
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
arguments?.let {
val value = FragmentBArgs.fromBundle(it).key
.......
}
.......
}
2. Examples
nav_main.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/nav_main"
app:startDestination="@id/avalFragment">
<fragment
android:id="@+id/avalFragment"
android:name="ir.MrMohamadHosein.navigationcomponent.AvalFragment"
android:label="fragment_aval"
tools:layout="@layout/fragment_aval" >
<action
android:id="@+id/action_avalFragment_to_dovomFragment"
app:destination="@id/dovomFragment" />
</fragment>
<fragment
android:id="@+id/dovomFragment"
android:name="ir.MrMohamadHosein.navigationcomponent.DovomFragment"
android:label="fragment_dovom"
tools:layout="@layout/fragment_dovom" >
<argument
android:name="MyName"
app:argType="string"
android:defaultValue="no-name" />
</fragment>
</navigation>
Note: Define the parameters you want to pass in the target Fragment, not define your pass parameters in the initial Fragment
1、MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
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">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
2、DownFragment, DovomFragment
2.1、DownstreamFragment
DownstreamFragment
class AvalFragment : Fragment() {
lateinit var binding: FragmentAvalBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentAvalBinding.inflate(layoutInflater)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.btnGoToSecondFragment.setOnClickListener {
findNavController().navigate(
AvalFragmentDirections.actionAvalFragmentToDovomFragment().setMyName("amir")
)
}
}
}
fragment_aval.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AvalFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="fragment aval"
android:textSize="36sp" />
<Button
android:id="@+id/btnGoToSecondFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="80dp"
android:text="go to second fragment" />
</FrameLayout>
2.2、DovomFragment
DovomFragment
class DovomFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_dovom, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val data = DovomFragmentArgs.fromBundle(requireArguments()).myName
Toast.makeText(context, data, Toast.LENGTH_SHORT).show()
}
}
fragment_dovom.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DovomFragment">
<TextView
android:textSize="36sp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fragment dovom" />
</FrameLayout>