Фрагмент транзакции с переходом - требуется уникальное имя перехода

Я хочу перейти от представления списка к подробному представлению, и поэтому я использую следующие OnClickListener в моем списке:

@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();
}

Мои функции возвращают уникальные имена, у меня есть два разных представления, но все равно это не работает. Я уже закомментировал ненужные функции и написал несколько уникальных имен транзакций от руки... Но, тем не менее, я получаю это исключение в строке первого addSharedElement:

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

РЕДАКТИРОВАТЬ

Без общих элементов все работает отлично...

5 ответов

Решение

Проблема в том, что addSharedElement НЕ устанавливает название транзакции для представления!

Так что в моем примере я должен установить его с помощью следующего кода:

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

ДО того, как я добавлю это мнение к FragmentTransaction...

Впоследствии следующие работы просто отлично и, как и ожидалось:

ft.addSharedElement(view.findViewById(R.id.ivLogo1), "1");
ft.addSharedElement(view.findViewById(R.id.ivLogo2), "2");

Вы должны установить одинаковое значение transitionName в элементе макета xml каждого фрагмента. Например:

Фрагмент А:

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

Фрагмент Б:

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

И код будет примерно таким:

yourTransaction.addSharedElement(view, view.transactionName)

Вам нужно только установить transitionName к вашему общему элементу. Нет необходимости выбирать его точно равным имени вашего общего элемента (который был передан как второй аргумент addSharedElement() метод).

Это имя (второй параметр addSharedElement() ) ДОЛЖЕН быть равен transitionName общего элемента в целевом фрагменте. Смотрите здесь.


Так что достаточно вставить:

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

перед вызовом addSharedElement(...),

Перед кликом

используйте этот код

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

Если твой onClickListener является частью вашего фрагмента, а не родительского Activityтогда вы делаете что-то не так здесь. Ваш фрагмент должен уведомить родительскую активность о том, что он хочет, и Activty должна с этим справиться (то есть путем замены фрагментов и т. Д.). Фрагмент никогда не должен делать это сам по себе. Кроме того, если все, что вам нужно, это перейти от подробного вида к списку, то я предполагаю, что вы ввели свой подробный вид из этого списка. Если это так, все, что вам нужно, это извлечь последний элемент (фрагмент фрагмента) из заднего стека. См.: https://developer.android.com/reference/android/app/FragmentManager.html

Другие вопросы по тегам