web-dev-qa-db-ja.com

共有要素の遷移の終了/再入力を理解する

Android Lで共有要素の遷移の基本的な調査を行っています。セットアップした簡単な例では、アクティビティ中に画面の上部から下部に画像ビューが変換されますトランジションとトランジション期間を延長して、動作を確認できるようにしました。これまで、共有要素のトランジションがどのように機能するかを理解しようとして、2つの問題が発生しました。

1)Enter/Returnトランジションのみを使用する場合(Exit/Reenterをnullに設定)。エンタートランジションは問題ありませんが、戻るボタンを押すと、ビューがしばらくアニメーション化されて停止し、最終的な位置に再表示されます。 この質問 に似ているようですが、すべてのExist/Reenterトランジションをnullに設定したため、なぜ発生するのかわかりません。

2)Exit/Reenterトランジションのみを使用する場合(Enter/Returnをnullに設定)。何も起こらず、ビューはデフォルトの入力遷移(300msの持続時間)のように画面を下に遷移し、戻るを押すと、ビューは元の位置に戻ります。

Exit/Reenterトランジションを使用するにはどうすればよいですか?

これが私のコードです:

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;
    }
}
14
user2100277

私が思い出したように、Lにはバグがあり、再入力遷移期間よりも時間がかかると、共有要素の戻り遷移が中断されます。 (呼び出し元のアクティビティで)再入力遷移期間を調整すると、MR1でバグが修正されるまで、中断の問題が修正されます。

終了と再入力の遷移は、共有要素の遷移が許可される前に何かを実行するためのものです。たとえば、共有要素を転送する前に持ち上げたい場合、それは共有要素の終了遷移で行われます。再入力は反対のことを行うために使用されます-ビューが転送された後にビューをドロップします。ほとんどのアプリはそれを必要としませんが、それは必要なまれなアプリのためにあります。

9
George Mount
  1. finishAfterTransition()onBackPressed()を呼び出さないでください。 Activityスーパークラスはすでにこれを行っています。

  2. requestFeature()の前にsuper.onCreate()を呼び出す必要があります。 _Window.FEATURE_ACTIVITY_TRANSITIONS_テーマ(または同様のもの)を使用している場合は、_Theme.Material_を要求する必要はありません。

  3. ここでは、setAllowEnterTransitionOverlap(false)setAllowReturnTransitionOverlap(false)の呼び出しは冗長です。これらは、アクティビティのウィンドウコンテンツ遷移がオーバーラップすることを決定します...アクティビティの共有要素コンテンツ遷移にはまったく影響しません。

  4. 共有要素の遷移を終了して再入力する必要があることはめったにありません。ほとんどの場合、代わりにEnter遷移とReturn遷移を使用する必要があります。共有要素の遷移の終了と再入力のみを設定し、共有要素の遷移の入力と戻りをnullのままにすると、呼び出されたアクティビティは、遷移の開始時に共有要素をアニメーション化する方法を知る方法がなくなり、アニメーションが壊れているように見えます。 。

12
Alex Lockwood