Tworzenie niestandardowej animacji przejścia

Niestandardowe przejście pozwala utworzyć animację, która jest niedostępna na z wbudowanymi klasami przejścia. Można na przykład zdefiniować niestandardowe przejście, które zmieni kolor pierwszego planu tekstu i pól do wprowadzania danych na szary, aby wskazać, że pola są wyłączone na nowym ekranie. Taka zmiana sprawi, że użytkownicy będą widzieli wyłączone przez Ciebie pola.

Niestandardowe przejście, takie jak jeden z wbudowanych typów przejść, powoduje stosowanie animacji do: wyświetleń podrzędnych zarówno sceny początkowej, jak i końcowej. Jednak w przeciwieństwie do wbudowanych typów przejść musisz dostarczyć kod, który przechwytuje wartości właściwości i generuje animacje. Możesz też zdefiniować podzbiór docelowych widoków animacji.

Z tej strony dowiesz się, jak przechwytywać wartości właściwości i generować animacje, aby tworzyć niestandardowe przejścia.

Przedłuż klasę przejścia

Aby utworzyć niestandardowe przejście, dodaj do projektu klasę, która rozszerza klasę Transition i zastępuje funkcje widoczne w tym fragmencie:

Kotlin

class CustomTransition : Transition() {

    override fun captureStartValues(transitionValues: TransitionValues) {}

    override fun captureEndValues(transitionValues: TransitionValues) {}

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {}

}

Java

public class CustomTransition extends Transition {

    @Override
    public void captureStartValues(TransitionValues values) {}

    @Override
    public void captureEndValues(TransitionValues values) {}

    @Override
    public Animator createAnimator(ViewGroup sceneRoot,
                                   TransitionValues startValues,
                                   TransitionValues endValues) {}
}

W sekcjach poniżej wyjaśniamy, jak zastąpić te funkcje.

Przechwytywanie wartości właściwości widoku danych

Animacje przejścia wykorzystują system animacji właściwości opisany w Omówienie animacji usługi. Usługa animacje zmieniają właściwość widoku z wartości początkowej na wartość końcową w zakresie okres, więc platforma musi zawierać zarówno wartość początkową, jak i końcową do utworzenia animacji.

Animacja właściwości zwykle potrzebuje jednak tylko niewielkiego podzbioru wszystkich właściwości widoku. . Na przykład animacja koloru wymaga wartości właściwości koloru, a ruch animacja wymaga wartości właściwości pozycji. Ponieważ wartości właściwości wymagane do animacji są związane z przejściem, schemat przejść nie zapewnia wszystkich wartości właściwości do przejścia. Zamiast tego platforma wywołuje funkcje wywołania zwrotnego, które umożliwiają przejście do rejestrować tylko potrzebne wartości właściwości i przechowywać je w ramach platformy.

Przechwytywanie wartości początkowych

Aby przekazać wartości widoku początkowego do platformy, zaimplementuj funkcję captureStartValues(transitionValues) . Platforma wywołuje tę funkcję dla każdego widoku w scenie początkowej. Funkcja to obiekt TransitionValues, który zawiera odwołanie do widoku danych i do wystąpienia Map, w których można zapisywać wartości w pobliżu. W swojej implementacji pobierz te wartości właściwości i przekaż je z powrotem do funkcji Google Cloud, przechowując je na mapie.

Aby mieć pewność, że klucz wartości właściwości nie koliduje z innymi TransitionValues, użyj tego schematu nazewnictwa:

package_name:transition_name:property_name

Ten fragment kodu przedstawia implementację funkcji captureStartValues():

Kotlin

class CustomTransition : Transition() {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private val PROPNAME_BACKGROUND = "com.example.android.customtransition:CustomTransition:background"

    override fun captureStartValues(transitionValues: TransitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues)
    }

    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private fun captureValues(transitionValues: TransitionValues) {
        // Get a reference to the view
        val view = transitionValues.view
        // Store its background property in the values map
        transitionValues.values[PROPNAME_BACKGROUND] = view.background
    }

    ...

}

Java

public class CustomTransition extends Transition {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private static final String PROPNAME_BACKGROUND =
            "com.example.android.customtransition:CustomTransition:background";

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues);
    }


    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private void captureValues(TransitionValues transitionValues) {
        // Get a reference to the view
        View view = transitionValues.view;
        // Store its background property in the values map
        transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
    }
    ...
}

Przechwyć wartości końcowe

Platforma wywołuje funkcję captureEndValues(TransitionValues) po jednym na każdy docelowy widok w ostatniej scenie. Pod każdym względem captureEndValues() działa tak samo jak captureStartValues().

Ten fragment kodu przedstawia implementację funkcji captureEndValues():

Kotlin

override fun captureEndValues(transitionValues: TransitionValues) {
    captureValues(transitionValues)
}

Java

@Override
public void captureEndValues(TransitionValues transitionValues) {
    captureValues(transitionValues);
}

W tym przykładzie zarówno captureStartValues(), jak i captureEndValues() funkcje wywołują metodę captureValues() w celu pobierania i przechowywania wartości. właściwość widoku danych, pobierany przez funkcję captureValues() jest taka sama, ale ma różne wartości w scenę początkową i końcową. Platforma udostępnia oddzielne mapy dla początkowych i końcowych wersji w postaci punktu widzenia.

Utwórz własnego animatora

Aby animować zmiany widoku między jego stanem w scenie początkowej a stanem w scenę końcową, dodaj animatora, zastępując createAnimator() . Gdy platforma wywołuje tę funkcję, jest ona przekazywana w widoku głównym sceny i TransitionValues obiektów, które zawierają wartość początkową i końcową zdjęcia.

Liczba wywołań funkcji createAnimator() przez platformę zależy od zmiany zachodzące między sceną początkową a końcową.

Rozważ na przykład ich wyciszanie, animacja rozjaśniania została zaimplementowana jako niestandardowe przejście. Jeśli scena początkowa ma pięć celów, którą z nich usunięto z sceny końcowej, a scena końcowa zawiera trzy cele z grupy scenę początkową i nowy cel, a ta struktura wywołuje createAnimator() 6 razy. Trzy wywołania animują zanikanie i zanikanie celów, które pozostają w obu scenie obiektów. Kolejne 2 wywołania animują zanikanie celów usuniętych z końcowej sceny. Jeden animuje pojawianie się nowego celu w ostatniej scenie.

W przypadku widoków docelowych, które występują zarówno w scenie początkowej, jak i końcowej, platforma zapewnia obiekt TransitionValues dla progów startValues i endValues argumentów. W przypadku widoków docelowych, które występują tylko na początku lub scenę końcową, platforma zapewnia obiekt TransitionValues, dla odpowiedniego argumentu, a null dla drugiego.

Aby zaimplementować funkcję createAnimator(ViewGroup, TransitionValues, TransitionValues) podczas tworzenia niestandardowe przejście, użyj przechwyconych wartości właściwości widoku, aby utworzyć obiekt Animator i zwrócić go do platformy. Przykładowa implementacja zobacz zajęcia ChangeColor w Przykład CustomPrzenoszenie. Więcej informacji na temat animatorów właściwości znajdziesz w artykule Animacja właściwości.

Stosowanie przejścia niestandardowego

Przejścia niestandardowe działają tak samo jak przejścia wbudowane. Możesz zastosować przeniesienie niestandardowe za pomocą menedżera przenoszenia, jak opisano w sekcji Przenoszenie subskrypcji.