android – Fragment Transactions with transition – Unique transitionNames are required-ThrowExceptions

Exception or error:

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…

How to solve:

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");

###

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)

###

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

###

before onClick

use this code

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

###

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

Leave a Reply

Your email address will not be published. Required fields are marked *