带有转换的片段交易 - 需要唯一的转换名称
Posted
技术标签:
【中文标题】带有转换的片段交易 - 需要唯一的转换名称【英文标题】:Fragment Transactions with transition - Unique transitionNames are required 【发布时间】:2015-08-31 02:49:41 【问题描述】:我想从列表视图转到详细视图,因此,我在列表中使用以下 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");
【讨论】:
非常感谢! 不需要指定与 SharedElement 的名称 完全相同的transitionName
。足以查看只有一个transitionName
。实际上,SharedElement 的名称必须等于目标片段中共享元素的transitionName
。见here。虽然这两个transitionName
s 可能需要相等(出于某些其他原因),但这并不是防止需要唯一的transitionNames错误的要求。【参考方案2】:
您必须在每个片段的 xml 布局元素中设置相同的 transitionName。例如:
片段 A:
<TextView
android:id="@+id/my_text_view"
...
android:transitionName="transtion_name_example"/>
片段 B:
<TextView
android:id="@+id/my_text_view"
...
android:transitionName="transtion_name_example"/>
代码会是这样的:
yourTransaction.addSharedElement(view, view.transactionName)
【讨论】:
【参考方案3】:您只需为您的共享元素设置一个transitionName
。 无需选择与您的共享元素的名称完全相同的名称(已作为addSharedElement()
方法的第二个参数传递)。
此名称(addSharedElement()
的第二个参数)必须等于目标片段中共享元素的transitionName
。见here。
所以插入就够了:
ViewCompat.setTransitionName(view.findViewById(R.id.ivLogo1), "AnyThing");
ViewCompat.setTransitionName(view.findViewById(R.id.ivLogo2), "EveryThing");
在调用addSharedElement(...)
之前。
【讨论】:
【参考方案4】:点击前
使用此代码
ViewCompat.setTransitionName(holder.ivImage, "value");
【讨论】:
【参考方案5】:如果您的 onClickListener
是片段的一部分,而不是父 Activity
,那么您在这里做错了。您的片段应该通知父活动它想要什么,而 Activty 应该处理它(即通过替换片段等)。片段不应该自己这样做。此外,如果您只需要从详细视图转到列表,那么我假设您从该列表输入了详细视图。如果是这样,您只需要从堆栈中弹出最后一个元素(片段视图片段)。见:https://developer.android.com/reference/android/app/FragmentManager.html
【讨论】:
只是为了澄清,唯一的问题是共享元素的动画......更改片段等工作正常。另一方面,你是对的,应该在活动中完成......我只是懒得把函数放在那里,因为我的片段流真的很容易......以上是关于带有转换的片段交易 - 需要唯一的转换名称的主要内容,如果未能解决你的问题,请参考以下文章
将 XSLT 转换的 XML 片段写入 XMLStreamWriter