15

我正在对 Android L 中的共享元素转换进行一些基本探索。我设置的简单示例有一个在活动转换期间从屏幕顶部转换到屏幕底部的图像视图,并且我已经延长了转换持续时间所以我可以看到工作正常。到目前为止,我遇到了两个问题,试图了解共享元素转换是如何工作的。

1) 仅使用 Enter/Return 转换时(Exit/Reenter 设置为 null)。输入过渡很好,但是当按下后退按钮时,视图会动画一段时间,停止,然后重新出现在最终位置。似乎与这个问题相似,但我已将所有 Exist/Reenter 转换设置为 null,所以不确定它为什么会发生。

2) 仅使用 Exit/Reenter 转换时(Enter/Return 设置为 null)。什么都没有发生,视图在屏幕上向下转换,就像它遵循默认的输入转换(300 毫秒持续时间)一样,当按下返回时,视图会弹回其原始位置。

如何使用退出/重新进入过渡?

这是我的代码:

activity_main.xml

<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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageView"
        android:src="@drawable/ic_launcher"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Animate!"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_alignParentStart="true" />

</RelativeLayout>

activity_second.xml

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/imageView2"
    android:src="@drawable/ic_launcher"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true" />

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
        getWindow().setAllowEnterTransitionOverlap(false);
        getWindow().setAllowReturnTransitionOverlap(false);


        getWindow().setSharedElementExitTransition(exitTransition());
        getWindow().setSharedElementReenterTransition(reenterTransition());
        //getWindow().setSharedElementExitTransition(null);
        //getWindow().setSharedElementReenterTransition(null);


        setContentView(R.layout.activity_main);

        final View iView = findViewById(R.id.imageView);
        iView.setTransitionName("image");

        final Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                ActivityOptions options = ActivityOptions
                        .makeSceneTransitionAnimation(MainActivity.this, iView, "image");
                startActivity(intent, options.toBundle());
            }
        });
    }

    private Transition exitTransition() {
        ChangeBounds bounds = new ChangeBounds();
        bounds.setInterpolator(new BounceInterpolator());
        bounds.setDuration(2000);

        return bounds;
    }

    private Transition reenterTransition() {
        ChangeBounds bounds = new ChangeBounds();
        bounds.setInterpolator(new OvershootInterpolator());
        bounds.setDuration(2000);

        return bounds;
    }
}

SecondActivity.java

public class SecondActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
        getWindow().setAllowEnterTransitionOverlap(false);
        getWindow().setAllowReturnTransitionOverlap(false);


        //getWindow().setSharedElementEnterTransition(enterTransition());
        //getWindow().setSharedElementReturnTransition(returnTransition());
        getWindow().setSharedElementEnterTransition(null);
        getWindow().setSharedElementReturnTransition(null);


        setContentView(R.layout.activity_second);

        final View iView = findViewById(R.id.imageView2);
        iView.setTransitionName("image");
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finishAfterTransition();
    }

    private Transition enterTransition() {
        ChangeBounds bounds = new ChangeBounds();
        bounds.setDuration(2000);

        return bounds;
    }

    private Transition returnTransition() {
        ChangeBounds bounds = new ChangeBounds();
        bounds.setInterpolator(new DecelerateInterpolator());
        bounds.setDuration(2000);

        return bounds;
    }
}
4

2 回答 2

13
  1. 你不应该打电话finishAfterTransition()onBackPressed()Activity超级类已经为您完成了这项工作。

  2. 你应该requestFeature()先打电话super.onCreate()。如果您使用主题(或类似主题),Window.FEATURE_ACTIVITY_TRANSITIONS则不需要请求。Theme.Material

  3. 在这里调用setAllowEnterTransitionOverlap(false)andsetAllowReturnTransitionOverlap(false)是多余的。这些决定了活动的窗口内容转换重叠......它们根本不影响活动的共享元素内容转换。

  4. 很少需要设置退出和重新进入共享元素转换。您几乎总是希望使用 enter 和 return 转换。如果只设置了退出和重新进入共享元素的过渡,而将进入和返回共享元素的过渡保留为空,那么被调用的活动将无法知道如何在过渡开始时为共享元素设置动画,并且动画会出现中断.

于 2014-12-07T18:27:10.060 回答
9

我记得,L 中有一个错误,如果共享元素返回转换的时间长于重新进入转换持续时间,则它会导致中断。如果您调整重新进入转换持续时间(在调用 Activity 上),那应该可以解决中断问题,直到 MR1 中的错误得到修复。

退出和重新进入转换用于在允许共享元素转换之前执行内容。例如,如果您想在传输共享元素之前提升它,这将在共享元素退出转换中完成。reenter 将用于做相反的事情——在视图被传回后删除视图。大多数应用程序都不需要它,但它是为罕见的应用程序提供的。

于 2014-12-08T01:34:35.617 回答