Una transizione personalizzata ti consente di creare un'animazione non disponibile in nessuna delle classi di transizione predefinite. Ad esempio, puoi definire una transizione personalizzata che imposti su grigio il colore di primo piano del testo e dei campi di immissione per indicare che i campi sono disattivati nella nuova schermata. Questo tipo di modifica consente agli utenti di vedere i campi che hai disattivato.
Una transizione personalizzata, come uno dei tipi di transizione integrati, applica le animazioni alle visualizzazioni secondarie sia della scena iniziale che di quella finale. Tuttavia, a differenza dei tipi di transizione integrati, devi fornire il codice che acquisisce i valori delle proprietà e genera le animazioni. Potresti anche 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.
Espandere la classe Transizione
Per creare una transizione personalizzata, aggiungi al progetto una classe che estenda la classe Transition
e sostituisca le 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à della vista da un valore iniziale a un valore finale in un determinato periodo di tempo, pertanto il framework deve avere sia i valori iniziale e finale della proprietà per creare l'animazione.
Tuttavia, un'animazione della proprietà di solito richiede solo un piccolo sottoinsieme di tutti i valori della proprietà della visualizzazione. Ad esempio, un'animazione di colore richiede valori della proprietà di colore, mentre un'animazione di movimento richiede valori della 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 della proprietà a una transizione. Il framework invoca invece funzioni di callback che consentono di eseguire una transizione per acquisire solo i valori delle proprietà di cui ha bisogno e memorizzarli nel framework.
Acquisisci i valori iniziali
Per passare i valori della visualizzazione iniziale 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 vista e un'istanza Map
in cui puoi memorizzare i valori della vista che ti interessano. Nell'implementazione, recupera questi valori delle proprietà e riassegnali al
framework archiviandoli nella mappa.
Per assicurarti che la chiave per un valore della proprietà non entri in conflitto con altre chiaviTransitionValues
, utilizza il seguente schema di denominazione:
package_name:transition_name:property_name
Lo snippet seguente 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, sia le funzioni captureStartValues()
sia captureEndValues()
invocano captureValues()
per recuperare e memorizzare i valori. La proprietà della 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.
Creare 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 sostituendo la funzione createAnimator()
. Quando il framework chiama questa funzione, passa la vista 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.
Ad esempio, prendi in considerazione un'animazione di dissolvenza in entrata o in uscita 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 l'attenuazione e l'aumento dell'intensità dei target che rimangono in entrambi gli oggetti della scena. Altre due chiamate animano lo svanimento dei target rimossi dalla scena finale. Una chiamata anima l'effetto di dissolvenza in entrata del nuovo target nella scena finale.
Per le visualizzazioni target esistenti sia nella scena iniziale che in quella finale, il framework fornisce un oggetto TransitionValues
sia per gli argomenti startValues
che per endValues
. Per le visualizzazioni target esistenti solo nella scena iniziale o 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 vista acquisiti per creare un oggetto Animator
e restituirlo al framework. Per un esempio di implementazione, consulta la classe ChangeColor
nell'esempio
CustomTransition. Per saperne di più sugli animatori delle proprietà, consulta
Animazione delle proprietà.
Applicare una transizione personalizzata
Le transizioni personalizzate funzionano come le transizioni integrate. Puoi applicare una transizione personalizzata utilizzando un gestore delle transizioni, come descritto in Applicare una transizione.