在共享元素 Activity 转换中,嵌套视图动画出现故障?

12
我一直在研究Android 5.0中的新API,并试图弄清楚在Activity转换期间是否可能分别对ViewGroup及其子项进行共享元素动画。
下面的截图给出了我试图实现的简化示例:

First Activity initial positions Second Activity final positions

在第一个活动中,深灰色框是居中于屏幕的ViewGroup,红色框是它的子View(我使用的布局XML代码可以在这里找到)。当用户点击深灰色框时,深灰色框应逐渐缩放以填充第二个活动的背景。同时,红色框应逐渐缩放并重新定位到第二个活动的左上角。

活动和动画代码

我用的Activity代码很简单:
/** FirstActivity.java */
public class FirstActivity extends Activity implements View.OnClickListener {
    private View mOuterBox, mInnerBox;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
        getWindow().setSharedElementExitTransition(new ChangeBounds());
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        mOuterBox = findViewById(R.id.outer_box);
        mInnerBox = findViewById(R.id.inner_box);
        mOuterBox.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Pair<View, String> outerBox = Pair.create(mOuterBox, mOuterBox.getTransitionName());
        Pair<View, String> innerBox = Pair.create(mInnerBox, mInnerBox.getTransitionName());
        Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this, outerBox, innerBox).toBundle();
        startActivity(new Intent(this, SecondActivity.class), bundle);
    }
}

/** SecondActivity.java */
public class SecondActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
        getWindow().setSharedElementEnterTransition(new ChangeBounds());
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }
}

问题

当我点击第一个活动中的深灰色框时,共享元素转换开始并且深灰色框很好地缩放以填充第二个活动的背景。 然而,红色框似乎根本没有动画效果。一旦转换开始,红色框就会在灰色框甚至还没有完成动画之前突然调整大小并将自己定位到第二个活动中的最终位置。

我的问题

是否可能独立地将ViewGroup和其某些/所有子视图作为共享元素在Activity转换中进行动画处理?如果可以,我做错了什么,我该怎么做才能确保子视图也得到动画处理?

如果你在理解我的描述时遇到了困难,这个示例项目的完整源代码可以在GitHub上获取,并且可运行的APK文件可以在这里下载(你需要一个运行Android 5.0的物理设备或模拟器来运行APK)。
1个回答

6

是的,您可以分别转换组及其内容。但是您刚发现了一个错误,这将在 L MR1 中得到修复。

看起来,在 L 中对此支持并不好。我建议您在第二个活动中将共享元素作为兄弟节点:

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/dark_gray"
        android:transitionName="outer_box"/>

    <RelativeLayout
        android:id="@+id/outer_box"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <View
            android:id="@+id/inner_box"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginLeft="50dp"
            android:layout_marginTop="50dp"
            android:background="@color/red"
            android:transitionName="inner_box" />
    </RelativeLayout>
</FrameLayout>

太棒了,我刚刚测试了这种方法,它完美地运行了!它有点hacky,但现在可以用...我想象一旦Lollipop的下一个版本修复了这个bug,就会有更优雅的解决方案。一旦bug被修复,我将接受这个答案,以强调这只是一个暂时的解决方法。谢谢! - Alex Lockwood
刚刚测试了一下,看起来这个 bug 已经被修复了。感谢你的帮助! - Alex Lockwood

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