Reputation: 3
I am writing an application on Kotlin (Android Studio), using jetpack.navigation architecture. There are two fragments: The first contains a list with class instances, which I display in the RecyclerView, the second for EditText (I fill in the client data). I also use Livedata and ViewModel. The problem is that when I go to the second fragment, fill in the data and confirm, I go to the 1st fragment. As I understand it, the following lines destroy the old Fragment1, and create a new one. the list on the first fragment is reset to zero (although the list is saved when you rotate the screen and minimize the application).
val client = Clients(id,name,secondName,thirdName, address, creditCard, bankNum)
val action = Fragment2Directions.actionFragment2ToFragment1(client)
findNavController().navigate(action)
I could not find how to solve problem using the navigation component. I will be very grateful.
Upvotes: 0
Views: 2124
Reputation: 1
As you are using ViewModel
s, I recommend that you use a shared ViewModel. The way it works is that multiple Fragments within the same Activity have access to the same ViewModel instance.
There is an example on Android Developers that fits your use case exactly. It shows how to use a shared ViewModel to do this using the master-detail navigation pattern and LiveData
. I recommend you take a look at it.
Why not to use Safe Args here: You can try using Safe Args to achieve what you are trying to achieve, but I strongly recommend against it: You would have to deal with somehow using Safe Args to pass your Client
objects between the Fragments back and forth (which means either sending each field individually or bundling) and you would have to manually update your LiveData
objects - which defeats the purpose of LiveData. Using a shared ViewModel
, you do not have to worry about any of that. No sending data back and forth, no taking your Client
objects apart or bundling, no manual updating of LiveData
objects - you simply access the same LiveData
instance from both Fragments through your ViewModel
.
Upvotes: 0
Reputation: 5185
To pass data between two fragments with jetpack navigation you have to use Safe Args
pass an argument section like
<fragment android:id="@+id/myFragment" >
<argument
android:name="myArg"
app:argType="integer"
android:defaultValue="0" />
</fragment>
add classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
in top level gradle file
and add the plugin apply plugin: "androidx.navigation.safeargs.kotlin"
now send the value like so
override fun onClick(v: View) {
val amountTv: EditText = view!!.findViewById(R.id.editTextAmount)
val amount = amountTv.text.toString().toInt()
val action = SpecifyAmountFragmentDirections.confirmationAction(amount)
v.findNavController().navigate(action)
}
and receive it as
val args: ConfirmationFragmentArgs by navArgs()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val tv: TextView = view.findViewById(R.id.textViewAmount)
val amount = args.amount
tv.text = amount.toString()
}
However safeargs works only for primitive types so you have to deconstruct and reconstruct if you're trying to pass Objects
Upvotes: 1