Rozpoczynanie aktywności przy użyciu animacji

Wypróbuj tworzenie wiadomości
Jetpack Compose to zalecany zestaw narzędzi interfejsu na Androida. Dowiedz się, jak pracować z animacjami w Compose.

Przejścia między aktywnościami w aplikacjach z Material Design zapewniają wizualne połączenia między różnymi stanami za pomocą animacji i przekształceń wspólnych elementów. Możesz określić niestandardowe animacje dla przejść wejścia i wyjścia oraz przejść elementów wspólnych między aktywnościami.

Rysunek 1 Przejście z elementami wspólnymi.

  • Przejście enter określa sposób, w jaki widoki w aktywności pojawiają się na scenie. Na przykład w przypadku przejścia explode views enter sceny, widoki wchodzą do niej z zewnątrz i przelatują do środka ekranu.
  • Przejście wyjścia określa sposób, w jaki widoki w aktywności opuszczają scenę. Na przykład w przypadku przejścia explode widok oddala się od środka.
  • Przejście elementów współdzielonych określa sposób przechodzenia widoków współdzielonych między 2 aktywnościami. Jeśli np. dwie aktywności mają ten sam obraz w różnych pozycjach i rozmiarach, przejście z elementem współdzielonym changeImageTransform przekształca i płynnie skaluje obraz między tymi aktywnościami.

Android obsługuje te przejścia wejścia i wyjścia:

  • explode: przesuwa widok w kierunku centrum sceny lub z powrotem do niego.
  • slide: przybliża lub oddala widok od jednego z brzegów sceny.
  • fade: dodaje lub usuwa widok ze sceny, zmieniając jego przezroczystość.

Jako przejście wejścia lub wyjścia obsługiwane jest dowolne przejście, które rozszerza klasę Visibility. Więcej informacji znajdziesz w dokumentacji interfejsu API dotyczącej klasy Transition.

Android obsługuje też te przejścia z elementów wspólnych:

  • changeBounds: animacja zmian w granicach układu widoków docelowych.
  • changeClipBounds: animuje zmiany w granicach klipu w przypadku widoków docelowych.
  • changeTransform: animuje zmiany skali i obrotu widoków docelowych.
  • changeImageTransform: animuje zmiany rozmiaru i skali obrazów docelowych.

Gdy włączysz w aplikacji przejścia między aktywnościami, między aktywnymi i nieaktywnymi aktywnościami zostanie włączone domyślne przejście z wypełnianiem.

Rysunek 2. Przejście między scenami z 1 elementem wspólnym

Przykładowy kod, który animuje przejścia między aktywnościami za pomocą wspólnych elementów, znajdziesz w artykule ActivitySceneTransitionBasic.

Sprawdzanie wersji systemu

Interfejsy API dotyczące przejścia między aktywnościami są dostępne w Androidzie 5.0 (poziom interfejsu API 21) lub nowszym. Aby zachować zgodność ze starszymi wersjami Androida, przed wywołaniem interfejsów API do obsługi tych funkcji sprawdź, czy system version jest dostępny w czasie wykonywania:

Kotlin

// Check if we're running on Android 5.0 or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Apply activity transition
} else {
    // Swap without transition
}

Java

// Check if we're running on Android 5.0 or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Apply activity transition
} else {
    // Swap without transition
}

Określanie przejść niestandardowych

Najpierw włącz przejścia zawartości okna za pomocą atrybutu android:windowActivityTransitions, gdy definiujesz styl, który dziedziczy z motywu Material. W definicji stylu możesz też określić przejścia wejścia, wyjścia i elementów współdzielonych:

<style name="BaseAppTheme" parent="android:Theme.Material">
  <!-- enable window content transitions -->
  <item name="android:windowActivityTransitions">true</item>

  <!-- specify enter and exit transitions -->
  <item name="android:windowEnterTransition">@transition/explode</item>
  <item name="android:windowExitTransition">@transition/explode</item>

  <!-- specify shared element transitions -->
  <item name="android:windowSharedElementEnterTransition">
    @transition/change_image_transform</item>
  <item name="android:windowSharedElementExitTransition">
    @transition/change_image_transform</item>
</style>

W tym przykładzie przejście change_image_transform jest zdefiniowane w ten sposób:

<!-- res/transition/change_image_transform.xml -->
<!-- (see also Shared Transitions below) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  <changeImageTransform/>
</transitionSet>

Element changeImageTransform odpowiada klasie ChangeImageTransform. Więcej informacji znajdziesz w dokumentacji interfejsu API Transition.

Aby włączyć w kodzie przejścia między oknami, wywołaj funkcję Window.requestFeature():

Kotlin

// Inside your activity (if you did not enable transitions in your theme)
with(window) {
    requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)

    // Set an exit transition
    exitTransition = Explode()
}

Java

// Inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);

// Set an exit transition
getWindow().setExitTransition(new Explode());

Aby określić przejścia w kodzie, wywołaj te funkcje za pomocą obiektu Transition:

Funkcje setExitTransition()setSharedElementExitTransition() definiują przejście wyjścia z aktywności wywołującej. Funkcje setEnterTransition()setSharedElementEnterTransition() definiują przejście wejścia dla wywoływanej aktywności.

Aby uzyskać pełny efekt przejścia, musisz włączyć przejścia zawartości okna zarówno w przypadku wywołującej, jak i wywoływanej aktywności. W przeciwnym razie wywoływane aktywo rozpoczyna przejście wyjściowe, ale potem widzisz przejścia okna, takie jak powiększanie lub zanikanie.

Aby jak najszybciej rozpocząć przejście wejścia, użyj funkcji Window.setAllowEnterTransitionOverlap() w wyzwanej aktywności. Dzięki temu możesz uzyskać bardziej efektowne przejścia.

Uruchamianie aktywności za pomocą przejść

Jeśli włączysz przejścia i ustawisz przejście wyjścia dla aktywności, przejście zostanie aktywowane, gdy uruchomisz inną aktywność:

Kotlin

startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle())

Java

startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

Jeśli dla drugiej aktywności ustawisz przejście wejścia, to przejście zostanie również aktywowane po rozpoczęciu tej aktywności. Aby wyłączyć przejścia podczas uruchamiania innej aktywności, podaj pakiet opcji null.

Rozpoczynanie aktywności przy użyciu elementu współdzielonego

Aby utworzyć animację przejścia między 2 ekranami, które mają wspólny element:

  1. Włącz przejścia między oknami w motywie.
  2. Określ przejście elementów współdzielonych w swoim stylu.
  3. Zdefiniuj przejście jako zasób XML.
  4. Przypisz wspólne nazwy elementom współdzielonym w obu układach za pomocą atrybutu android:transitionName.
  5. Użyj funkcji ActivityOptions.makeSceneTransitionAnimation().

Kotlin

// Get the element that receives the click event
val imgContainerView = findViewById<View>(R.id.img_container)

// Get the common element for the transition in this activity
val androidRobotView = findViewById<View>(R.id.image_small)

// Define a click listener
imgContainerView.setOnClickListener( {
    val intent = Intent(this, Activity2::class.java)
    // Create the transition animation - the images in the layouts
    // of both activities are defined with android:transitionName="robot"
    val options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot")
    // Start the new activity
    startActivity(intent, options.toBundle())
})

Java

// Get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// Get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// Define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(this, Activity2.class);
        // Create the transition animation - the images in the layouts
        // of both activities are defined with android:transitionName="robot"
        ActivityOptions options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot");
        // Start the new activity
        startActivity(intent, options.toBundle());
    }
});

W przypadku udostępnionych widoków dynamicznych wygenerowanych w kodzie użyj funkcji View.setTransitionName(), aby określić wspólną nazwę elementu w obu aktywnościach.

Aby odwrócić animację przejścia do sceny po zakończeniu drugiego działania, wywołaj funkcję Activity.finishAfterTransition() zamiast Activity.finish().

Uruchamianie aktywności z wieloma współdzielonymi elementami

Aby utworzyć animację przejścia między scenami w przypadku 2 aktywności, które mają więcej niż 1 wspólny element, zdefiniuj te wspólne elementy w obu układach za pomocą atrybutu android:transitionName lub użyj funkcji View.setTransitionName() w obu aktywnościach i utwórz obiekt ActivityOptions w ten sposób:

Kotlin

// Rename the Pair class from the Android framework to avoid a name clash
import android.util.Pair as UtilPair
...
val options = ActivityOptions.makeSceneTransitionAnimation(this,
        UtilPair.create(view1, "agreedName1"),
        UtilPair.create(view2, "agreedName2"))

Java

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
        Pair.create(view1, "agreedName1"),
        Pair.create(view2, "agreedName2"));