Фрагментные транзакции с переходом - требуются уникальные имена перехода
Я хочу перейти от представления списка к подробному представлению, и поэтому я использую следующий 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
РЕДАКТИРОВАТЬ
Без общих элементов все работает отлично...
Ответы
Ответ 1
Проблема заключается в том, что 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");
Ответ 2
Вам нужно только установить имя transitionName
в свой общий элемент. Нет необходимости выбирать его точно так же, как имя вашего общего элемента (который был передан как второй аргумент метода addSharedElement()
).
Это имя (второй параметр addSharedElement()
) ДОЛЖЕН быть равно transitionName
общего элемента в целевом фрагменте. См. Здесь.
Так что достаточно вставить:
ViewCompat.setTransitionName(view.findViewById(R.id.ivLogo1), "AnyThing");
ViewCompat.setTransitionName(view.findViewById(R.id.ivLogo2), "EveryThing");
перед addSharedElement(...)
.
Ответ 3
Если onClickListener
является частью вашего фрагмента, а не родительская Activity
, то вы делаете вещи неправильно здесь. Ваш фрагмент должен уведомлять родительскую активность о том, чего она хочет, и Activty должна иметь дело с ней (т.е. Путем замены фрагментов и т.д.). Фрагмент никогда не должен делать это сам по себе. Кроме того, если вам нужно только перейти от подробного представления к списку, я предполагаю, что вы ввели свой подробный вид из этого списка. Если это так, все, что вам нужно, - вырезать последний элемент (фрагмент фрагмента фрагмента) из предыдущего стека. См. Https://developer.android.com/reference/android/app/FragmentManager.html.
Ответ 4
перед onClick
используйте этот код
ViewCompat.setTransitionName(holder.ivImage, "value");