Fragment Transactions with transition - Unique transitionNames are required
Asked Answered
B

5

23

I want to go from a list view to the detail view and therefore, I use following OnClickListener in my list:

@Override
public void onClick(View view)
{
    Bet bet = (Bet)view.getTag();
    FragmentManager fm = getActivity().getSupportFragmentManager();
    BetDetailFragment f = BetDetailFragment.create(bet);
    String tag = f.getClass().getName();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move));
        f.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move));
    }

    FragmentTransaction ft = fm.beginTransaction()
            .replace(R.id.frame_container, f, tag)
            .addToBackStack(tag);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        L.d(this, "TRANS: " + TransitionUtil.getTransitionNameBetLogo1(bet) + "|" + view.findViewById(R.id.ivLogo1));
        L.d(this, "TRANS: " + TransitionUtil.getTransitionNameBetLogo2(bet) + "|" + view.findViewById(R.id.ivLogo2));
        ft.addSharedElement(view.findViewById(R.id.ivLogo1), "1");//TransitionUtil.getTransitionNameBetLogo1(bet));
        ft.addSharedElement(view.findViewById(R.id.ivLogo2), "2");//TransitionUtil.getTransitionNameBetLogo2(bet));
    }
    ft.commit();
}

My functions return unique names, I have two different views, but still it does not work. I already commented unnecessary functions out and wrote some unique transaction names in there by hand... But still, I get this exception, in the line of the first addSharedElement:

java.lang.IllegalArgumentException: Unique transitionNames are required for all sharedElements
        at android.support.v4.app.BackStackRecord.addSharedElement

EDIT

Without the shared elements, everything is working perfectly fine...

Brooklime answered 15/6, 2015 at 14:40 Comment(0)
B
55

The problem is, that addSharedElement does NOT set the transaction name of the view!

So in my example I would have to set it with following code:

ViewCompat.setTransitionName(view.findViewById(R.id.ivLogo1), "1");
ViewCompat.setTransitionName(view.findViewById(R.id.ivLogo2), "2");

BEFORE I add this views to the FragmentTransaction...

Afterwards following works just fine and as expected:

ft.addSharedElement(view.findViewById(R.id.ivLogo1), "1");
ft.addSharedElement(view.findViewById(R.id.ivLogo2), "2");
Brooklime answered 16/6, 2015 at 16:6 Comment(2)
Thank you very much for this!Crysta
Don't need to assign a transitionName exactly equal to SharedElement's name. It's enough to view has only a transitionName. Actually SharedElement's name MUST be equal to transitionName of shared element in the destination fragment. See here. Although these two transitionNames may be required to be equal (for some other reasons) but is not a requirement to prevent of Unique transitionNames are required error.Indestructible
N
6

You must set the same transitionName in the xml layout element of each fragment. For example:

Fragment A:

<TextView
 android:id="@+id/my_text_view"
 ...
 android:transitionName="transtion_name_example"/>

Fragment B:

<TextView
 android:id="@+id/my_text_view"
 ...
 android:transitionName="transtion_name_example"/>

And the code will be something like this:

yourTransaction.addSharedElement(view, view.transactionName)
Nemesis answered 16/9, 2018 at 15:54 Comment(0)
I
3

You need to only set a transitionName to your shared element. There is no need for choosing it exactly equal to the name of your shared element (that has been passed as the second argument of addSharedElement() method).

This name (second parameter of addSharedElement()) MUST be equal to transitionName of the shared element in the destination fragment. See here.


So it's enough to insert:

ViewCompat.setTransitionName(view.findViewById(R.id.ivLogo1), "AnyThing");
ViewCompat.setTransitionName(view.findViewById(R.id.ivLogo2), "EveryThing");

before invoking addSharedElement(...).

Indestructible answered 21/7, 2018 at 23:35 Comment(0)
B
1

before onClick

use this code

ViewCompat.setTransitionName(holder.ivImage, "value");
Boykin answered 30/10, 2017 at 13:30 Comment(0)
F
0

If your onClickListener is part of your fragment, not parent Activity, then you are doing things wrong here. Your fragment should notify parent activity what it wants and Activty should deal with it (i.e. by replacing fragments etc). Fragment should never do this by itself. Also if all you need is to go from detail view to list, then I assume you entered your detail view from that list. If so, all you need is to pop last element (fragment view fragment) fromt back stack. See: https://developer.android.com/reference/android/app/FragmentManager.html

Ferullo answered 15/6, 2015 at 14:53 Comment(1)
just to clarify, the only problem is the animation of the shared elements... Changing fragments and so is working fine. To the other point, you're right, should be done in the activity... I was just to lazy to put the function there, as my fragment flows are really easy...Brooklime

© 2022 - 2024 — McMap. All rights reserved.