0

I have two fragments and I want to use shared element transitions between them. But the I still want to use navigation action to pass data between them.

From the first fragment, I only have image uri loaded using Glide and it's from the recyclerView. I'm passing the image description as well as the image id-> fileId

  val action =
            MediaFragmentDirections.actionNavMediaToPhotoGalleryEditImageFragment(
                imageUri,
                description,
                fileId
            )
        findNavController().navigate(action)

In the second fragment I get the uri from args and display it with glide again

private val args: MediaFragmentPhotoNameArgs by navArgs()
...


   val photoIV = args.imageData
        /*load the image sent from media fragment*/
        Glide.with(this)
            .load(photoIV)
            .into(photoGalleryImage)

In the documentation this is what is there

val extras = FragmentNavigatorExtras(view1 to "hero_image")

view.findNavController().navigate(
    R.id.confirmationAction,
    null, // Bundle of args
    null, // NavOptions
    extras)

I don't know how i can pass action with it because I need the other variables in the second fragment as well.

Please how can i achieve this?

Oluwafemi
  • 306
  • 1
  • 4
  • 14

1 Answers1

2

You need to create a Navigator.Extras object and pass it as the second parameter to navigate:

val extras = FragmentNavigatorExtras(imageView to "transition_name")

val action = MediaFragmentDirections.actionNavMediaToPhotoGalleryEditImageFragment(
                imageUri,
                description,
                fileId
            )
        findNavController().navigate(action, extras)

Where imageView is the view that user clicks on it and the transition_name is the transition name that you also have to set it to target view.

To add transition name in xml:

android:transitionName="transition_name"

To add transition name in class:

ViewCompat.setTransitionName(yourView,"transition_name")

And note that for a recycler view, you need to set a unique name to each view.


RecyclerView example:

Set position based name as transition name to image view when user clicks on a view:

fun onClick(view: View, position : Int){
val imageView = view.findViewById<ImageView>(R.id.image)
ViewCompat.setTransitionName(imageView,"image$position")

//Pass the position to target fragment:
val extras = FragmentNavigatorExtras(imageView to "image$position")

val action = MediaFragmentDirections.actionNavMediaToPhotoGalleryEditImageFragment(
                imageUri,
                description,
                position
            )
        findNavController().navigate(action, extras)
}

Set transition name to target image view when fragment starts:

ViewCompat.setTransitionName(targetImageView,"image$position")
Amir
  • 1,628
  • 20
  • 28
  • Thanks, but how can I set the Unique name to each view? is there a way to use the fileId in the xml in this case? @Amir – Oluwafemi Jul 28 '21 at 10:18
  • Also, I'm getting this `Required: Pair Found: Pair` while trying to setup the extra ` val extras = FragmentNavigatorExtras(imageUri to "hero_image")` – Oluwafemi Jul 28 '21 at 10:20
  • @user11874398 As for the unique name, you can set transition name programmatically on the view that user clicks using the position and send the position to second fragment and set target transition name again. – Amir Jul 28 '21 at 11:01
  • @user11874398 As for the error you are getting. As I already said in my post, you need to pass the `ImageView`'s view instead of `imageUri`! – Amir Jul 28 '21 at 11:03
  • @user11874398 Please mark the answer as accepted if that's what you want. – Amir Aug 07 '21 at 02:59