使用共享元素转换和ChangeImageTransform在两个活动之间对ImageView进行动画处理

17

我试图在Android API 21中将一个ImageView动画到另一个位置,但由于Android L Preview中的"MoveImage"已被删除,所以我改用"ChangeImageTransform",但文档中的示例代码并不起作用(两个图像分别进行动画处理)。

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeImageTransform>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeImageTransform>
</transitionSet>

有没有可用的示例?谢谢!

2个回答

30

为了在两个具有共享元素的活动之间制作屏幕过渡动画, 您可以阅读本文并按照提到的步骤执行:

  1. 在主题中启用窗口内容转换。
  2. 在样式中指定共享元素过渡。
  3. 将您的转换定义为XML资源。
  4. 使用android:transitionName属性为两个布局中的共享元素分配一个公共名称。
  5. 使用ActivityOptions.makeSceneTransitionAnimation()方法。

关于第三步,根据文档

结合ChangeBounds使用,ChangeImageTransform允许ImageViews平滑地动画化内容,这些内容更改了大小、形状或ImageView.ScaleType。

res/transition/your_transition.xml应该是这样的:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeBounds>
    <changeImageTransform>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeImageTransform>
</transitionSet>

或者只需要对ivA和ivB进行动画处理,可以像这样简单处理:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds/>
    <changeImageTransform/>
</transitionSet>

1
我一直在尝试让它工作,但是新活动的进入转换会淡入,而ImageView是旧活动中最后显示的东西。不过退出转换可以正常工作。 - Timothy Logan
@TimmahhTimmahh,你是否按照文档中的所有步骤进行了操作?请提供更多信息,谢谢 :) - Yi-Ping Shih
1
我找到了问题所在。我将视图添加到ListView的标题中,因此在转换之后才能找到它。解决方案是推迟转换,然后在ListView的OnPreDrawListener中启动它。 - Timothy Logan
1
@Radu,为什么不能让某人自己想明白呢? - EvilDuck
@TimmahhTimmahh的解决方案对我有效。我看到了退出动画,但没有进入动画。您可以在此处检查解决方案: http://www.androiddesignpatterns.com/2015/03/activity-postponed-shared-element-transitions-part3b.html - Tooroop
显示剩余3条评论

8
我已经按照这个指南、其他一些指南以及参考资料使它工作起来了。
在这种样式中设置了一个转换。我将其放在res/transition下:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeBounds>
    <changeImageTransform>
        <targets>
            <target android:targetId="@id/ivA" />
            <target android:targetId="@id/ivB" />
        </targets>
    </changeImageTransform>
</transitionSet>

在源ImageView和目标ImageView中,您需要添加一个名称标记。名称必须相同。
<ImageView
...
android:transitionName="MYTRANSITIONVIEW"

/>

在styles.xml中,添加到应用程序主题中:
<item name="android:windowContentTransitions">true</item>
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowSharedElementEnterTransition">@transition/my_transition</item>
<item name="android:windowSharedElementExitTransition">@transition/my_transition</item>

我正在片段中运行此代码,因此我以以下方式启动新活动:

Bundle bundle = null;

if (activity != null) {
    ActivityOptionsCompat options =
                ActivityOptionsCompat.makeSceneTransitionAnimation(activity, Frag2_, "MYTRANSITIONVIEW");
    bundle = options.toBundle();
}
activity.startActivity(i, bundle);

它适用于API 21客户端。由于XML标签无效,因此在API 16客户端上无法工作。

希望这可以帮到您。

稍微更新一下,为了在退出时获得反向转换,我不得不调用

supportFinishAfterTransition();

与其使用finish(),不如使用其他方法;


1
它应该是res/transition,而不是res/transitions。 - Sandip Fichadiya

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