Niestandardowe przejście pozwala utworzyć animację, która jest niedostępna w żadnej z wbudowanych klas przejścia. Możesz np. zdefiniować niestandardowe przejście, które zmieni kolor pierwszego planu tekstów i pól do wprowadzania danych na szary, by wskazać, że na nowym ekranie pola są wyłączone. Dzięki tej zmianie użytkownicy będą mogli zobaczyć wyłączone pola.
Niestandardowe przejście, np. jeden z wbudowanych typów przejść, powoduje zastosowanie animacji do widoków podrzędnych zarówno sceny początkowej, jak i końcowej. Jednak w odróżnieniu od 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 widoków docelowych dla animacji.
Na tej stronie dowiesz się, jak rejestrować wartości właściwości i generować animacje, aby tworzyć niestandardowe przejścia.
Rozszerzanie zajęć
Aby utworzyć niestandardowe przejście, dodaj do projektu klasę, która rozszerza klasę Transition
i zastąp 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 dowiesz się, jak zastępować te funkcje.
Przechwytywanie wartości właściwości widoku danych
Animacje przejść korzystają z systemu animacji właściwości opisanego w artykule Omówienie animacji właściwości. Animacje właściwości zmieniają w określonym przedziale czasu wartość początkową na wartość końcową. Platforma musi mieć zarówno wartość początkową, jak i końcową właściwości, aby utworzyć animację.
W przypadku animacji właściwości potrzebny jest jednak zazwyczaj tylko niewielki podzbiór wszystkich wartości właściwości widoku. Na przykład animacja koloru wymaga wartości właściwości koloru, a animacja ruchu – wartości właściwości pozycji. Wartości właściwości potrzebne animacji są związane z konkretnym przejściem, więc platforma przejść nie podaje każdej wartości właściwości przejścia. Zamiast tego platforma wywołuje funkcje wywołań zwrotnych, które umożliwiają przechwycenie tylko potrzebnych wartości właściwości i zapisanie ich w platformie.
Przechwytywanie wartości początkowych
Aby przekazać do platformy wartości początkowego widoku, zaimplementuj funkcję captureStartValues(transitionValues)
. Platforma wywołuje tę funkcję w przypadku każdego widoku w scenie początkowej. Argumentem funkcji jest obiekt TransitionValues
zawierający odniesienie do widoku i wystąpienie Map
, w którym możesz przechowywać potrzebne wartości widoku. W swojej implementacji pobierz wartości właściwości i przekaż je z powrotem do platformy, zapisując je na mapie.
Aby upewnić się, że klucz wartości właściwości nie koliduje z innymi kluczami TransitionValues
, użyj tego schematu nazewnictwa:
package_name:transition_name:property_name
Ten fragment kodu zawiera 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)
raz przy każdym wyświetleniu docelowym w scenie końcowej. We wszystkich pozostałych przypadkach captureEndValues()
działa tak samo jak captureStartValues()
.
Ten fragment kodu zawiera 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 funkcje captureStartValues()
, jak i captureEndValues()
wywołują metodę captureValues()
w celu pobrania i przechowywania wartości. Właściwość widoku pobierana przez captureValues()
jest taka sama, ale ma różne wartości w scenie początkowej i końcowej. Platforma tworzy oddzielne mapy stanu początkowego i końcowego widoku.
Tworzenie niestandardowych animacji
Aby animować zmiany w widoku między stanem w scenie początkowej a jego stanem w scenie końcowej, użyj animatora, zastępując funkcję createAnimator()
. Gdy platforma wywołuje tę funkcję, przekazuje ją do widoku głównego sceny i do obiektów TransitionValues
zawierających przechwycone wartości początkowe i końcowe.
Liczba wywołań funkcji createAnimator()
przez platformę zależy od zmian, które zaszły między sceną początkową i końcową.
Rozważmy np. animację z efektem rozjaśniania lub rozjaśniania
jako niestandardowe przejście. Jeśli scena początkowa ma pięć celów, z których dwa są usuwane ze sceny końcowej, a scena końcowa zawiera trzy cele ze sceny początkowej i nowy cel, platforma wywołuje createAnimator()
sześć razy.
Trzy z nich animują zanikanie i rozjaśnianie celów, które pozostają w obu obiektach sceny. Dwa kolejne wywołania animują zanikanie celów usuniętych z ostatniej sceny. Jedno wywołanie animuje pojawienie się nowego celu w końcowej scenie.
W przypadku widoków docelowych, które występują zarówno w scenie początkowej, jak i końcowej, platforma udostępnia obiekt TransitionValues
dla argumentów startValues
i endValues
. W przypadku widoków docelowych, które istnieją tylko na scenie początkowej lub końcowej, platforma udostępnia obiekt TransitionValues
dla odpowiedniego argumentu i obiekt null
dla drugiego argumentu.
Aby wdrożyć funkcję createAnimator(ViewGroup, TransitionValues, TransitionValues)
podczas tworzenia niestandardowego przejścia, użyj przechwyconych wartości właściwości widoku danych, aby utworzyć obiekt Animator
i zwrócić go do platformy. Przykładową implementację znajdziesz w klasie ChangeColor
w przykładzie
CustomMove. Więcej informacji o animatorach właściwości znajdziesz w artykule Animacja właściwości.
Stosowanie niestandardowego przejścia
Przejścia niestandardowe działają tak samo jak przejścia wbudowane. Przejście niestandardowe możesz zastosować za pomocą menedżera przenoszenia zgodnie z opisem w sekcji Stosowanie przejścia.