Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La clase .NET Multi-platform App UI (.NET MAUI) Animation es el bloque de construcción de todas las animaciones de .NET MAUI, con los métodos de extensión de la clase ViewExtensions que crea uno o más objetos Animation.
Al crear un objeto Animation, se debe especificar un número de parámetros, incluidos los valores inicial y final de la propiedad que se está animando, y una función de devolución de llamada que cambia el valor de la propiedad. Un Animation objeto también puede mantener una colección de animaciones secundarias que se pueden ejecutar y sincronizar. Para obtener más información, vea Animaciones para niños.
La ejecución de una animación creada con la Animation clase , que puede incluir o no animaciones secundarias, se logra llamando al Commit método . Este método especifica la duración de la animación y, junto con otros elementos, un callback que controla si se repite la animación.
Nota:
La Animation clase tiene una IsEnabled propiedad que se puede examinar para determinar si el sistema operativo ha deshabilitado las animaciones, como cuando se activa el modo de ahorro de energía.
En Android, las animaciones respetan la configuración de animación del sistema:
- Si las animaciones del sistema están deshabilitadas (ya sea por características de accesibilidad o características de desarrollador), las nuevas animaciones saltarán inmediatamente a su estado terminado.
- Si el modo de ahorro de energía del dispositivo está activado mientras las animaciones están en curso, las animaciones saltarán inmediatamente a su estado terminado.
- Si las duraciones de animación del dispositivo se establecen en cero (deshabilitadas) mientras las animaciones están en curso y la versión de la API es 33 o superior, las animaciones saltarán inmediatamente a su estado finalizado.
Crear una animación
Al crear un Animation objeto, normalmente, se requieren un mínimo de tres parámetros, como se muestra en el ejemplo de código siguiente:
var animation = new Animation(v => image.Scale = v, 1, 2);
En este ejemplo, una animación de la propiedad Scale de la instancia Image se define desde un valor de 1 hasta un valor de 2. El valor animado se pasa a la devolución de llamada especificada como primer argumento, donde se usa para cambiar el valor de la propiedad Scale.
La animación se inicia con una llamada al Commit método :
animation.Commit(this, "SimpleAnimation", 16, 2000, Easing.Linear, (v, c) => image.Scale = 1, () => true);
Nota:
El Commit método no devuelve un Task objeto . En su lugar, las notificaciones se proporcionan a través de métodos de devolución de llamada.
Los argumentos siguientes se especifican en el Commit método :
- El primer argumento (
owner) identifica al propietario de la animación. Puede ser el elemento visual en el que se aplica la animación u otro elemento visual, como la página. - El segundo argumento (
name) identifica la animación con un nombre. El nombre se combina con el propietario para identificar de forma única la animación. Esta identificación única se puede usar para determinar si la animación se está ejecutando (AnimationIsRunning) o para cancelarla (AbortAnimation). - El tercer argumento (
rate) indica el número de milisegundos entre cada llamada al método de devolución de llamada definido en el Animation constructor. - El cuarto argumento (
length) indica la duración de la animación, en milisegundos. - El quinto argumento (Easing) define la función de aceleración que se va a usar en la animación. Como alternativa, la función de aceleración se puede especificar como argumento para el Animation constructor. Para obtener más información sobre las funciones de aceleración, consulte Funciones de aceleración.
- El sexto argumento (
finished) es una devolución de llamada que se ejecutará cuando se haya completado la animación. Esta devolución de llamada toma dos argumentos, en donde el primer argumento indica un valor final, y el segundo argumento es unboolestablecido entruesi se cancela la animación. Como alternativa,finishedpuede especificarse como un argumento del constructor Animation. Sin embargo, con una sola animación, si se especifica una devolución de llamada en elfinishedconstructor y en el Animation método, solo se ejecutará la devolución de llamada especificada en el Commit método. - El séptimo argumento (
repeat) es un callback que permite repetir la animación. Se llama al final de la animación, y devolvertrueindica que se debe repetir la animación.
En el ejemplo anterior, el efecto general es crear una animación que aumente la propiedad Scale de una instancia Image de 1 a 2, a lo largo de 2 segundos (2000 milisegundos), usando la función de aceleración Linear. Cada vez que se completa la animación, su Scale propiedad se restablece a 1 y la animación se repite.
Nota:
Las animaciones simultáneas, que se ejecutan independientemente entre sí se pueden construir creando un Animation objeto para cada animación y, a continuación, llamando al Commit método en cada animación.
Animaciones hijo
La Animation clase también admite animaciones secundarias, que son Animation objetos a los que se agregan otros Animation objetos como elementos secundarios. Esto permite ejecutar y sincronizar una serie de animaciones. En el ejemplo de código siguiente se muestra cómo crear y ejecutar animaciones secundarias:
var parentAnimation = new Animation();
var scaleUpAnimation = new Animation(v => image.Scale = v, 1, 2, Easing.SpringIn);
var rotateAnimation = new Animation(v => image.Rotation = v, 0, 360);
var scaleDownAnimation = new Animation(v => image.Scale = v, 2, 1, Easing.SpringOut);
parentAnimation.Add(0, 0.5, scaleUpAnimation);
parentAnimation.Add(0, 1, rotateAnimation);
parentAnimation.Add(0.5, 1, scaleDownAnimation);
parentAnimation.Commit(this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState(true, false));
Como alternativa, el ejemplo de código se puede escribir de forma más concisa:
new Animation
{
{ 0, 0.5, new Animation (v => image.Scale = v, 1, 2) },
{ 0, 1, new Animation (v => image.Rotation = v, 0, 360) },
{ 0.5, 1, new Animation (v => image.Scale = v, 2, 1) }
}.Commit (this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState (true, false));
En ambos ejemplos, se crea un objeto primario Animation , al que se agregan objetos adicionales Animation . Los dos primeros argumentos para el Add método especifican cuándo comenzar y finalizar la animación secundaria. Los valores de argumento deben estar comprendidos entre 0 y 1, y representar el período relativo dentro de la animación principal, cuando la animación secundaria especificada estará activa. Por lo tanto, en este ejemplo, scaleUpAnimation estará activo durante la primera mitad de la animación, se scaleDownAnimation activará durante la segunda mitad de la animación y rotateAnimation estará activo durante toda la duración.
El efecto general de este ejemplo es que la animación se produce durante 4 segundos (4000 milisegundos).
scaleUpAnimation Anima la propiedad Scale de 1 a 2, durante 2 segundos. A scaleDownAnimation continuación, anima la Scale propiedad de 2 a 1, durante 2 segundos. Mientras se producen ambas animaciones de escala, el rotateAnimation anima la propiedad Rotation de 0 a 360, durante 4 segundos. Ambas animaciones de escalado también usan funciones de suavizado. La SpringIn función de aceleración hace que la Image instancia se reduzca inicialmente antes de aumentarse y la SpringOut función de aceleración hace Image que sea menor que su tamaño real hacia el final de la animación completa.
Hay varias diferencias entre un Animation objeto que usa animaciones secundarias y una que no:
- Cuando se usan animaciones secundarias, la
finisheddevolución de llamada de una animación secundaria indica cuándo la animación secundaria se ha completado, y lafinisheddevolución de llamada pasada al método Commit indica cuándo se ha completado toda la animación. - Cuando se usan animaciones secundarias, la devolución
truederepeatllamada del Commit método no hará que la animación se repita, pero la animación seguirá ejecutándose sin nuevos valores. - Al incluir una función de aceleración en el Commit método y la función de aceleración devuelve un valor mayor que 1, se finalizará la animación. Si la función de amortiguación devuelve un valor menor que 0, el valor se limita a 0. Para usar una función de aceleración que devuelva un valor inferior a 0 o superior a 1, debe especificarse en una de las animaciones secundarias en lugar de en el método Commit.
La Animation clase también incluye WithConcurrent métodos que se pueden usar para agregar animaciones secundarias a un objeto primario Animation . Sin embargo, los valores de argumento de begin y finish no están restringidos del 0 al 1. Solo esa parte de la animación secundaria que corresponde a un intervalo de 0 a 1 estará activa. Por ejemplo, si una WithConcurrent llamada al método define una animación secundaria que tiene como destino una Scale propiedad de 1 a 6, pero con valores de begin -2 y finish 3, el begin valor de -2 corresponde a un Scale valor de 1 y el finish valor de 3 corresponde a un Scale valor de 6. Dado que los valores fuera del intervalo de 0 y 1 no juegan ninguna parte en una animación, la Scale propiedad solo se animará de 3 a 6.
Cancelar una animación
Una aplicación puede cancelar una animación personalizada mediante una llamada al método de extensión AbortAnimation.
this.AbortAnimation ("SimpleAnimation");
Dado que las animaciones se identifican de forma única mediante una combinación del propietario de la animación y el nombre de la animación, el propietario y el nombre especificados al ejecutar la animación deben especificarse para cancelarla. Por lo tanto, este ejemplo cancelará inmediatamente la animación denominada SimpleAnimation que pertenece a la página.
Crear una animación personalizada
Los ejemplos que se muestran aquí hasta ahora han demostrado animaciones que podrían lograrse igualmente con los métodos de la ViewExtensions clase . Sin embargo, la clase Animation tiene la ventaja de tener acceso al método de devolución de llamada, que se ejecuta cuando cambia el valor animado. Esto permite que el callback implemente cualquier animación que se desee. Por ejemplo, en el ejemplo de código siguiente se anima la BackgroundColor propiedad de una página estableciendo en Color los valores creados por el Color.FromHsla método , con valores de tono comprendidos entre 0 y 1:
new Animation (callback: v => BackgroundColor = Color.FromHsla (v, 1, 0.5),
start: 0,
end: 1).Commit (this, "Animation", 16, 4000, Easing.Linear, (v, c) => BackgroundColor = Colors.Black);
La animación resultante da la impresión de que el fondo de la página avanza a través de los colores del arco iris.
Creación de un método de extensión de animación personalizado
Los métodos de extensión de la ViewExtensions clase animan una propiedad de su valor actual a un valor especificado. Esto dificulta la creación, por ejemplo, de un ColorTo método de animación que se puede usar para animar un color de un valor a otro. Esto se debe a que los distintos controles tienen propiedades diferentes de tipo Color. Aunque la VisualElement clase define una BackgroundColor propiedad, esta no siempre es la Color propiedad deseada para animar.
La solución a este problema es no tener el ColorTo método como destino una propiedad determinada Color . En su lugar, se puede escribir con un método de devolución de llamada que pasa el valor interpolado Color al llamador. Además, el método tomará argumentos de inicio y fin Color.
El ColorTo método se puede implementar como un método de extensión que usa el Animate método de la AnimationExtensions clase para proporcionar su funcionalidad. Esto se debe a que el Animate método se puede usar para dirigir las propiedades que no son de tipo double, como se muestra en el ejemplo de código siguiente:
public static class ViewExtensions
{
public static Task<bool> ColorTo(this VisualElement self, Color fromColor, Color toColor, Action<Color> callback, uint length = 250, Easing easing = null)
{
Func<double, Color> transform = (t) =>
Color.FromRgba(fromColor.Red + t * (toColor.Red - fromColor.Red),
fromColor.Green + t * (toColor.Green - fromColor.Green),
fromColor.Blue + t * (toColor.Blue - fromColor.Blue),
fromColor.Alpha + t * (toColor.Alpha - fromColor.Alpha));
return ColorAnimation(self, "ColorTo", transform, callback, length, easing);
}
public static void CancelAnimation(this VisualElement self)
{
self.AbortAnimation("ColorTo");
}
static Task<bool> ColorAnimation(VisualElement element, string name, Func<double, Color> transform, Action<Color> callback, uint length, Easing easing)
{
easing = easing ?? Easing.Linear;
var taskCompletionSource = new TaskCompletionSource<bool>();
element.Animate<Color>(name, transform, callback, 16, length, easing, (v, c) => taskCompletionSource.SetResult(c));
return taskCompletionSource.Task;
}
}
El método Animate requiere un argumento transform, que es un método de devolución de llamada. La entrada a esta devolución de llamada siempre es un double valor comprendido entre 0 y 1. Por lo tanto, en este ejemplo, el ColorTo método define su propia transformación Func que acepta un double valor comprendido entre 0 y 1 y que devuelve un Color valor correspondiente a ese valor. El Color valor se calcula interpolando los Redvalores , Green, Bluey Alpha de los dos argumentos proporcionados Color . A continuación, el valor Color se pasa al método de devolución de llamada para aplicar a una propiedad. Este enfoque permite al ColorTo método animar cualquier propiedad especificada Color :
await Task.WhenAll(
label.ColorTo(Colors.Red, Colors.Blue, c => label.TextColor = c, 5000),
label.ColorTo(Colors.Blue, Colors.Red, c => label.BackgroundColor = c, 5000));
await this.ColorTo(Color.FromRgb(0, 0, 0), Color.FromRgb(255, 255, 255), c => BackgroundColor = c, 5000);
await boxView.ColorTo(Colors.Blue, Colors.Red, c => boxView.Color = c, 4000);
En este ejemplo de código, el método ColorTo anima los TextColor y BackgroundColor de un Label, la propiedad BackgroundColor de una página y la propiedad Color de un BoxView.