带轮播的Android共享元素转换可能已损坏?

时间:2016-02-09 16:50:23

标签: android android-transitions shared-element-transition

(请参阅代码后的更新。)

我有一个带有旋转视图的屏幕,我希望将其转换到另一个屏幕,理想情况是使用Android的内置共享元素转换功能。但是,即使旋转相同,设置View旋转时产生的动画也会被破坏。我查看了共享元素转换的各种转换效果,“ChangeTransform”特别提到了旋转(并查看代码确认了这一点)。使用它或不使用它具有相同的结果。 (也就是说,明确地设置或仅使用默认设置,动画外观的结果没有变化,我将在下面描述。)

那会发生什么?让我举例解释一下。让我们进行两项活动 - 我们将摆脱所有片段,因此我们知道延迟的过渡不会妨碍它们 - 称之为MainActivity和AnotherActivity。 MainActivity启动具有共享元素转换的AnotherActivity活动。取两个视图,viewOnene和viewTwo。 ViewOne没有轮播。 ViewTwo在MainActivity中设置了旋转,但没有设置AnotherActivity。在MainActivity中,两个视图都在左侧,而在AnotherActivity中,两个视图都在右侧。它们有不同的尺寸。

以下是今后发生的事情:

  • ViewOne动画显示目标位置,并适当缩放尺寸。这看起来很好,很有希望。
  • ViewTwo弹出无旋转(例如,即时旋转为0),然后动画到目标位置和大小。看起来很可怕。

这是向后退时发生的事情:

  • ViewOne会反转动画,一切看起来都不错。
  • ViewTwo动画回到目标位置,有点太大了。然后它会弹出一个略有不同的位置和大小(更大,更奇怪)和目标旋转并平移和缩放到位。这看起来很糟糕。

你可能需要自己看一下。这里:https://youtu.be/cUlVZgmJV_A

我试过直接通过代码更改转换,从样式中查看TransitionSet和引用,结果是一样的。就像轮换时(无论是来自代码还是XML),转换被分成两半。

我创建了一个小项目来演示,如果需要可以共享整个项目。但是,我怀疑我可能只是遗漏了一些简单的东西,特别是因为一个视图在转换时工作正常。

我期望发生的是通过翻译和缩放顺利改变的轮换。对于动画师来说,这是相对简单的,但是如果可能的话,我想避免手动创建共享元素转换。

以下是相关文件的相关部分:

MainActivity.java

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final View viewOne = findViewById(R.id.viewOne);
        final View viewTwo = findViewById(R.id.viewTwo);

        viewOne.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, AnotherActivity.class);
                Pair<View, String> viewOneTx = new Pair<>(viewOne, "view_one");
                Pair<View, String> viewTwoTx = new Pair<>(viewTwo, "view_two");

                ArrayList<Pair<View, String>> viewsList = new ArrayList<>();

                viewsList.add(viewOneTx);
                viewsList.add(viewTwoTx);

                ActivityOptionsCompat options;

                //noinspection unchecked
                Pair<View, String>[] sharedElements = (Pair<View, String>[]) new Pair[viewsList.size()];
                viewsList.toArray(sharedElements);
                //noinspection unchecked
                options = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, sharedElements);


                ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle());
            }
        });
    }

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:clipChildren="false"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.test.transitionplay.MainActivity">


    <View
        android:id="@+id/viewOne"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#f0f"
        android:transitionName="view_one" />


    <View
        android:id="@+id/viewTwo"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:background="#f00"
        android:rotation="-45"
        android:layout_alignParentBottom="true"
        android:transitionName="view_two" />
</RelativeLayout>

activity_another.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.test.transitionplay.AnotherActivity">

    <View
        android:id="@+id/anotherViewOne"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_alignParentRight="true"
        android:background="#f0f"
        android:transitionName="view_one" />

    <View
        android:id="@+id/anotherViewTwo"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:background="#f00"
        android:transitionName="view_two" />

</RelativeLayout>

更新#1

我相信,我已将问题缩小到ChangeTransform。在line 282附近,有一个注释,“清除变换属性,以便我们可以使用动画矩阵”,而代码,实际上,在视图上将所有常规变换属性(如旋转和平移)设置为零。这可以解释为什么UI会看到这种行为......

更新#2

我决定尝试对旋转进行简单的变换,因为实际的移动(由ChangeBounds处理)似乎正在起作用。当我这样做时,变换接收的开始和结束视图不仅相同,而且旋转为零(第二个活动的视图 - 我设置了一个标签来确认)。结果?与ChangeTransform相同的问题......所以也许这个问题处于更高的水平?

那就是说,我很难相信它根本不起作用......我一定是想错过一些东西。

更新#3

在视频中,结尾处的“反弹”,最值得注意的是返回,似乎根本不是来自共享元素转换。在此期间,我一直在努力解决这个问题,即使我的其他部分大部分都在工作,那部分仍然存在。这提供了更多的证据,证明我可能遗漏了一些重要的东西 - 或者它已经破碎了。

0 个答案:

没有答案