Previously there was no way or guaranteeing that the data handed across in Bundles was what was expected. The safe-args plugin seeks to address this:
dependencies {
...
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
// Add the safe-args plugin after any others:
apply plugin: 'androidx.navigation.safeargs'
android {
compileSdkVersion 28
...
In the Navigation component select the Fragment which is passing on arguments and add Arguments using the + symbol next to the Arguments section of the GUI. Give each a name and specify type if necessary.
import ...
class TitleFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val binding: FragmentTitleBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_title, container, false)
binding.playButton.setOnClickListener {v: View ->
// v.findNavController().navigate(R.id.action_titleFragment_to_nextFragment) // Before safe-args
v.findNavController().navigate(TitleFragmentDirections.actionTitleFragmentToNextFragment(firstParameter, secondParameter)) // With safe-args. Creates a class *Directions based on Fragment name with associated actions which take the parameters to be passed on
}
setHasOptionsMenu(true)
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
inflater?.inflate(R.menu.overflow_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return NavigationUI.onNavDestinationSelected(item!!, view!!.findNavController())
|| super.onOptionsItemSelected(item)
}
}
In the receiving fragment:
import ...
class NextFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val binding: FragmentTitleBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_next, container, false)
val args = NextFragmentArgs.fromBundle(arguments!!) // Get arguments.
Toast.makeText(context, "First Parameter: ${args.firstParameter}, Second Parameter: ${args.secondParameter}", Toast.LENGTH_SHORT).show() // Use the Bundled parameters
return binding.root
}
}
