片段事务与转换 - 需要唯一的转换名称

23

我想从列表视图转到详细视图,因此我在我的列表中使用以下OnClickListener

我希望从列表视图转到详细视图,因此我在列表中使用以下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个回答

55
问题在于,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");

非常感谢您这个! - Fernando Jascovich
不需要将transitionName分配为与SharedElement的名称完全相等。只要视图只有一个transitionName就足够了。实际上,*SharedElement的名称必须等于目标片段中*共享元素transitionName*。请参见此处。尽管这两个transitionName可能需要相等(出于其他原因),但这不是防止需要唯一的transitionNames*错误的要求。 - Mir-Ismaili

6

您需要在每个片段的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相等。请参见这里


所以,只需插入

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

在调用addSharedElement(...)之前。

1

在 onClick 之前

使用这段代码

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

0
如果您的onClickListener是片段的一部分,而不是父Activity,那么您在这里做错了。您的片段应该通知父活动它想要什么,然后活动应该处理它(例如通过替换片段等)。片段本身不应该这样做。此外,如果您只需要从详细视图返回到列表,则我假设您是从该列表进入详细视图的。如果是这样,您所需的就是从后堆栈中弹出最后一个元素(片段视图片段)。请参见:https://developer.android.com/reference/android/app/FragmentManager.html

只是为了澄清,唯一的问题是共享元素的动画...更改片段等都正常工作。至于另一点,你是对的,应该在活动中完成...我只是太懒了,没有把函数放在那里,因为我的片段流非常简单... - prom85

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接