Cómo crear una animación de transición personalizada

Una transición personalizada te permite crear una animación que no está disponible en ninguno de las clases de transición integradas. Por ejemplo, puedes definir una transición personalizada que convierta el color de primer plano de los campos de texto y de entrada a gris para indicar que los campos están inhabilitados en la nueva pantalla. Este tipo de cambio ayuda a los usuarios a ver los campos que inhabilitaste.

Una transición personalizada, al igual que uno de los tipos de transición integrados, aplica animaciones a vistas secundarias de la escena inicial y final. Sin embargo, a diferencia de los tipos de transición integrados, debe proporcionar el código que captura los valores de las propiedades y genera animaciones. Es posible que también quieras definir un subconjunto de vistas objetivo para la animación.

En esta página, se explica cómo capturar valores de propiedades y generar animaciones para crear transiciones personalizadas.

Cómo extender la clase de transición

Para crear una transición personalizada, agrega una clase a tu proyecto que extienda la clase Transition y anula las funciones que se muestran en el siguiente fragmento:

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) {}
}

En las siguientes secciones, se explica cómo anular estas funciones.

Cómo capturar valores de propiedades de vista

Las animaciones de transición utilizan el sistema de animación de propiedades que se describe en Descripción general de la animación de propiedades. Propiedad las animaciones cambian una propiedad de vista de un valor inicial a un valor final por encima de un valor especificado de tiempo, por lo que el framework debe tener los valores inicial y final de la propiedad para construir la animación.

Sin embargo, una animación de propiedad suele requerir solo un pequeño subconjunto de todas las propiedades de la vista. de salida. Por ejemplo, una animación de color necesita valores de propiedad de color, mientras que un movimiento La animación necesita valores de propiedad de posición. Como los valores de propiedad necesarios para una animación son específicos de una transición, el marco de trabajo de transiciones no proporciona todos los valores de las propiedades a una transición. En cambio, el framework invoca las funciones de devolución de llamada que permiten una transición a captar solo los valores de propiedad que necesita y almacenarlos en el marco de trabajo

Cómo capturar valores iniciales

Para pasar los valores de vista iniciales al framework, implementa la captureStartValues(transitionValues) . El framework llama a esta función para cada vista en la escena inicial. La función es un objeto TransitionValues que contiene una referencia a la vista y a una instancia de Map, en la que puedes almacenar los valores de vista que quieren. En tu implementación, recupera estos valores de propiedad y pásalos de vuelta al de Terraform al almacenarlas en el mapa.

Para garantizar que la clave de un valor de propiedad no entre en conflicto con otro TransitionValues, usa el siguiente esquema de nombres:

package_name:transition_name:property_name

El siguiente fragmento muestra una implementación de la función 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());
    }
    ...
}

Cómo capturar valores finales

El framework llama a la función captureEndValues(TransitionValues). una vez por cada vista de destino en la escena final. En todos los demás aspectos, captureEndValues() funciona igual que captureStartValues().

En el siguiente fragmento de código, se muestra una implementación de la función captureEndValues():

Kotlin

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

Java

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

En este ejemplo, tanto captureStartValues() como captureEndValues() invocan a captureValues() para recuperar y almacenar valores. La propiedad de vista que recupera captureValues() es la misma, pero tiene valores diferentes en el escenas de inicio y finalización. El framework mantiene mapas separados para el inicio y la finalización estados de una vista.

Cómo crear un animador personalizado

Para animar los cambios en una vista entre su estado en la escena inicial y su estado en la escena final, proporciona un animador anulando el createAnimator() . Cuando el framework llama a esta función, pasa a la vista raíz de la escena y al Objetos TransitionValues que contienen los valores de inicio y finalización que capturaste.

La cantidad de veces que el framework llama a la función createAnimator() depende de la cambios que ocurren entre las escenas inicial y final.

Por ejemplo, considera un fundido de salida o animación de fundido de entrada implementada como una transición personalizada. Si la escena inicial tiene cinco objetivos, cuáles se quitan de la escena final, y la escena final tiene los tres objetivos escena inicial más un nuevo destino y, luego, el framework llama a createAnimator() seis veces. Tres de las llamadas animan el fundido de salida y de entrada de los objetivos que permanecen en ambas escenas. objetos. Dos llamadas más animan el fundido de salida de los objetivos que se quitaron de la escena final. Uno anima el fundido de entrada del nuevo objetivo en la escena final.

Para las vistas objetivo que existen en las escenas inicial y final, el framework proporciona un objeto TransitionValues para startValues y endValues. Para las vistas de destino que solo existen en el inicio o en escena final, el framework proporciona un objeto TransitionValues para el argumento correspondiente y null para el otro.

Para implementar la función createAnimator(ViewGroup, TransitionValues, TransitionValues) cuando crees una transición personalizada, usa los valores de propiedad de vista que capturaste para crear un objeto Animator y devolverlo al framework. Para una implementación de ejemplo, consulta la clase ChangeColor en CustomTransition. Para obtener más información sobre los animadores de propiedades, consulta Animación de propiedades.

Cómo aplicar una transición personalizada

Las transiciones personalizadas funcionan igual que las transiciones integradas. Puedes aplicar una transición personalizada con un administrador de transiciones, como se describe en Cómo aplicar una transición