Una transizione personalizzata ti consente di creare un'animazione non disponibile in nessuna delle classi di transizione integrate. Ad esempio, puoi definire una transizione personalizzata che imposta il colore di primo piano dei campi di testo e di input su grigio per indicare che i campi sono disattivati nella nuova schermata. Questo tipo di modifica aiuta gli utenti a visualizzare i campi che hai disattivato.
Una transizione personalizzata, come uno dei tipi di transizione integrati, applica animazioni alle visualizzazioni secondarie delle scene di inizio e fine. Tuttavia, a differenza dei tipi di transizione integrati, devi fornire il codice che acquisisce i valori delle proprietà e genera le animazioni. Potresti anche voler definire un sottoinsieme di visualizzazioni target per l'animazione.
Questa pagina spiega come acquisire i valori delle proprietà e generare animazioni per creare transizioni personalizzate.
Estendi la classe Transition
Per creare una transizione personalizzata, aggiungi una classe al progetto che estenda la classe Transition ed esegui l'override delle funzioni mostrate nel seguente snippet:
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) {} }
Le sezioni seguenti spiegano come eseguire l'override di queste funzioni.
Acquisisci i valori delle proprietà della visualizzazione
Le animazioni di transizione utilizzano il sistema di animazione delle proprietà descritto in Panoramica dell'animazione delle proprietà. Le animazioni delle proprietà modificano una proprietà di visualizzazione da un valore iniziale a un valore finale in un periodo di tempo specificato, pertanto il framework deve avere sia i valori iniziale che finale della proprietà per costruire l'animazione.
Tuttavia, un'animazione delle proprietà di solito richiede solo un piccolo sottoinsieme di tutti i valori delle proprietà della visualizzazione. Ad esempio, un'animazione del colore richiede valori delle proprietà del colore, mentre un'animazione di movimento richiede valori delle proprietà di posizione. Poiché i valori delle proprietà necessari per un'animazione sono specifici di una transizione, il framework delle transizioni non fornisce ogni valore delle proprietà a una transizione. Il framework richiama invece le funzioni di callback che consentono a una transizione di acquisire solo i valori delle proprietà di cui ha bisogno e di memorizzarli nel framework.
Acquisisci i valori iniziali
Per passare i valori iniziali della visualizzazione al framework, implementa la funzione captureStartValues(transitionValues). Il framework chiama questa funzione per ogni visualizzazione nella scena iniziale. L'argomento della funzione è un oggetto TransitionValues che contiene un riferimento alla visualizzazione e un'istanza Map in cui puoi memorizzare i valori della visualizzazione che vuoi. Nell'implementazione, recupera questi valori delle proprietà e restituiscili al framework memorizzandoli nella mappa.
Per assicurarti che la chiave di un valore di proprietà non sia in conflitto con altre chiavi TransitionValues, utilizza il seguente schema di denominazione:
package_name:transition_name:property_name
Il seguente snippet mostra un'implementazione della funzione 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()); } ... }
Acquisisci i valori finali
Il framework chiama la funzione captureEndValues(TransitionValues) una volta per ogni visualizzazione target nella scena finale. Per tutti gli altri aspetti, captureEndValues() funziona come captureStartValues().
Il seguente snippet di codice mostra un'implementazione della funzione captureEndValues():
Kotlin
override fun captureEndValues(transitionValues: TransitionValues) { captureValues(transitionValues) }
Java
@Override public void captureEndValues(TransitionValues transitionValues) { captureValues(transitionValues); }
In questo esempio, le funzioni captureStartValues() e captureEndValues() richiamano captureValues() per recuperare e memorizzare i valori. La proprietà di visualizzazione recuperata da captureValues() è la stessa, ma ha valori diversi nelle scene iniziale e finale. Il framework gestisce mappe separate per gli stati iniziale e finale di una visualizzazione.
Crea un animatore personalizzato
Per animare le modifiche a una visualizzazione tra il suo stato nella scena iniziale e il suo stato nella scena finale, fornisci un animatore eseguendo l'override della funzione createAnimator(). Quando il framework chiama questa funzione, passa la visualizzazione principale della scena e gli oggetti TransitionValues che contengono i valori iniziale e finale acquisiti.
Il numero di volte in cui il framework chiama la funzione createAnimator() dipende dalle modifiche che si verificano tra le scene iniziale e finale.
Considera, ad esempio, un'animazione di dissolvenza in uscita o in entrata implementata come transizione personalizzata. Se la scena iniziale ha cinque target, di cui due vengono rimossi dalla scena finale, e la scena finale ha i tre target della scena iniziale più un nuovo target, il framework chiama createAnimator() sei volte.
Tre delle chiamate animano la dissolvenza in uscita e in entrata dei target che rimangono in entrambi gli oggetti scena. Altre due chiamate animano la dissolvenza in uscita dei target rimossi dalla scena finale. Una chiamata anima la dissolvenza in entrata del nuovo target nella scena finale.
Per le visualizzazioni target che esistono sia nella scena iniziale che in quella finale, il framework fornisce un oggetto TransitionValues per gli argomenti startValues e endValues. Per le visualizzazioni target che esistono solo nella scena iniziale o in quella finale, il framework fornisce un oggetto TransitionValues per l'argomento corrispondente e null per l'altro.
Per implementare la funzione createAnimator(ViewGroup, TransitionValues, TransitionValues) quando crei
una transizione personalizzata, utilizza i valori delle proprietà della visualizzazione acquisiti per creare un Animator oggetto e restituirlo al framework. Per un'implementazione di esempio,
consulta la classe ChangeColor nell'esempio
CustomTransition. Per ulteriori informazioni sugli animatori delle proprietà, consulta
Animazione delle proprietà.
Applica una transizione personalizzata
Le transizioni personalizzate funzionano come le transizioni integrate. Puoi applicare una transizione personalizzata utilizzando un gestore delle transizioni, come descritto in Applica una transizione.