Fragment Transactions with transition - Unique transitionNames are required

17.3k views Asked by At

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...

5

There are 5 answers

2
prom85 On BEST ANSWER

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");
1
Marcin Orlowski On

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

0
ycesar On

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)
0
Mir-Ismaili On

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(...).

0
Ahamadullah Saikat On

before onClick

use this code

ViewCompat.setTransitionName(holder.ivImage, "value");