Animaciones simples en Xamarin.Forms
La clase ViewExtensions proporciona métodos de extensión que se pueden usar para construir animaciones simples. En este artículo se muestra cómo crear y cancelar animaciones mediante la clase ViewExtensions.
La ViewExtensions
clase proporciona los siguientes métodos de extensión que se pueden usar para crear animaciones sencillas:
CancelAnimations
cancela todas las animaciones.FadeTo
anima laOpacity
propiedad de un objetoVisualElement
.RelScaleTo
aplica un aumento incremental animado o disminución a laScale
propiedad de .VisualElement
RotateTo
anima laRotation
propiedad de un objetoVisualElement
.RelRotateTo
aplica un aumento incremental animado o disminución a laRotation
propiedad de .VisualElement
RotateXTo
anima laRotationX
propiedad de un objetoVisualElement
.RotateYTo
anima laRotationY
propiedad de un objetoVisualElement
.ScaleTo
anima laScale
propiedad de un objetoVisualElement
.ScaleXTo
anima laScaleX
propiedad de un objetoVisualElement
.ScaleYTo
anima laScaleY
propiedad de un objetoVisualElement
.TranslateTo
anima lasTranslationX
propiedades yTranslationY
de .VisualElement
De forma predeterminada, cada animación tardará 250 milisegundos. Sin embargo, se puede especificar una duración para cada animación al crear la animación.
Nota
La ViewExtensions
clase proporciona un método de LayoutTo
extensión. Sin embargo, este método está diseñado para ser utilizado por diseños para animar transiciones entre estados de diseño que contienen cambios de tamaño y posición. Por lo tanto, solo deben usarse las Layout
subclases.
Los métodos de extensión de animación de la ViewExtensions
clase son asincrónicos y devuelven un Task<bool>
objeto . El valor devuelto es false
si la animación se completa y true
si se cancela la animación. Por lo tanto, los métodos de animación normalmente se deben usar con el await
operador , lo que permite determinar fácilmente cuándo se ha completado una animación. Además, después es posible crear animaciones secuenciales con métodos de animación posteriores que se ejecutan después de que se haya completado el método anterior. Para obtener más información, vea Animaciones compuestas.
Si hay un requisito para permitir que una animación se complete en segundo plano, se puede omitir el await
operador. En este escenario, los métodos de extensión de animación volverán rápidamente después de iniciar la animación, con la animación que se produce en segundo plano. Esta operación se puede aprovechar al crear animaciones compuestas. Para obtener más información, vea Animaciones compuestas.
Para obtener más información sobre el await
operador, vea Async Support Overview( Información general de soporte técnico asincrónico).
Animaciones únicas
Cada método de extensión de ViewExtensions
implementa una sola operación de animación que cambia progresivamente una propiedad de un valor a otro durante un período de tiempo. En esta sección se explora cada operación de animación.
Rotación
En el ejemplo de código siguiente se muestra el uso del RotateTo
método para animar la Rotation
propiedad de un Image
objeto :
await image.RotateTo (360, 2000);
image.Rotation = 0;
Este código anima la Image
instancia girando hasta 360 grados durante 2 segundos (2000 milisegundos). El RotateTo
método obtiene el valor de propiedad actual Rotation
para el inicio de la animación y, a continuación, gira de ese valor a su primer argumento (360). Una vez completada la animación, la propiedad de Rotation
la imagen se restablece a 0. Esto garantiza que la Rotation
propiedad no permanezca en 360 después de que finalice la animación, lo que impediría rotaciones adicionales.
En las capturas de pantalla siguientes se muestra la rotación en curso en cada plataforma:
Nota
Además del RotateTo
método , también RotateXTo
hay métodos y RotateYTo
que animan las RotationX
propiedades y RotationY
, respectivamente.
Rotación relativa
En el ejemplo de código siguiente se muestra el uso del RelRotateTo
método para aumentar o disminuir incrementalmente la Rotation
propiedad de un Image
objeto :
await image.RelRotateTo (360, 2000);
Este código anima la Image
instancia girando 360 grados desde su posición inicial durante 2 segundos (2000 milisegundos). El RelRotateTo
método obtiene el valor de propiedad actual Rotation
para el inicio de la animación y, a continuación, gira de ese valor al valor más su primer argumento (360). Esto garantiza que cada animación siempre será un giro de 360 grados desde la posición inicial. Por lo tanto, si se invoca una nueva animación mientras una animación ya está en curso, comenzará desde la posición actual y puede terminar en una posición que no sea un incremento de 360 grados.
En las capturas de pantalla siguientes se muestra la rotación relativa en curso en cada plataforma:
Ampliación
En el ejemplo de código siguiente se muestra el uso del ScaleTo
método para animar la Scale
propiedad de un Image
objeto :
await image.ScaleTo (2, 2000);
Este código anima la instancia mediante el Image
escalado vertical hasta el doble de su tamaño durante 2 segundos (2000 milisegundos). El ScaleTo
método obtiene el valor de propiedad actual Scale
(valor predeterminado de 1) para el inicio de la animación y, a continuación, escala de ese valor a su primer argumento (2). Esto tiene el efecto de expandir el tamaño de la imagen al doble de su tamaño.
En las capturas de pantalla siguientes se muestra el escalado en curso en cada plataforma:
Nota
Además del ScaleTo
método , también ScaleXTo
hay métodos y ScaleYTo
que animan las ScaleX
propiedades y ScaleY
, respectivamente.
Escalado relativo
En el ejemplo de código siguiente se muestra el uso del RelScaleTo
método para animar la Scale
propiedad de un Image
objeto :
await image.RelScaleTo (2, 2000);
Este código anima la instancia mediante el Image
escalado vertical hasta el doble de su tamaño durante 2 segundos (2000 milisegundos). El RelScaleTo
método obtiene el valor de propiedad actual Scale
para el inicio de la animación y, a continuación, escala de ese valor al valor más su primer argumento (2). Esto garantiza que cada animación siempre será un escalado de 2 desde la posición inicial.
Escalado y rotación con delimitadores
Las AnchorX
propiedades y AnchorY
establecen el centro de escalado o rotación de las Rotation
propiedades y Scale
. Por lo tanto, sus valores también afectan a los RotateTo
métodos y ScaleTo
.
Dado que Image
se ha colocado en el centro de un diseño, el siguiente ejemplo de código muestra la rotación de la imagen alrededor del centro del diseño estableciendo su AnchorY
propiedad :
double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
image.AnchorY = radius / image.Height;
await image.RotateTo(360, 2000);
Para girar la Image
instancia alrededor del centro del diseño, las AnchorX
propiedades y AnchorY
deben establecerse en valores relativos al ancho y al alto de Image
. En este ejemplo, el centro de Image
se define para que esté en el centro del diseño, por lo que el valor predeterminado AnchorX
de 0,5 no requiere cambiar. Sin embargo, la AnchorY
propiedad se vuelve a definir para que sea un valor desde la parte superior del Image
hasta el punto central del diseño. Esto garantiza que Image
realiza una rotación completa de 360 grados alrededor del punto central del diseño, como se muestra en las capturas de pantalla siguientes:
Traducción
En el ejemplo de código siguiente se muestra el uso del TranslateTo
método para animar las TranslationX
propiedades y TranslationY
de :Image
await image.TranslateTo (-100, -100, 1000);
Este código anima la Image
instancia traduciéndolo horizontal y verticalmente más de 1 segundo (1000 milisegundos). El TranslateTo
método traduce simultáneamente la imagen de 100 píxeles a la izquierda y 100 píxeles hacia arriba. Esto se debe a que los argumentos primero y segundo son números negativos. Proporcionar números positivos traduciría la imagen a la derecha y hacia abajo.
En las capturas de pantalla siguientes se muestra la traducción en curso en cada plataforma:
Nota
Si un elemento se coloca inicialmente fuera de la pantalla y luego se traduce en la pantalla, después de traducir el diseño de entrada del elemento permanece fuera de la pantalla y el usuario no puede interactuar con él. Por lo tanto, se recomienda disponer una vista en su posición final y, a continuación, realizar las traducciones necesarias.
Corrección selectiva
En el ejemplo de código siguiente se muestra el uso del FadeTo
método para animar la Opacity
propiedad de un Image
objeto :
image.Opacity = 0;
await image.FadeTo (1, 4000);
Este código anima la Image
instancia de desvaneciéndose en más de 4 segundos (4000 milisegundos). El FadeTo
método obtiene el valor de propiedad actual Opacity
para el inicio de la animación y, a continuación, desaparece de ese valor a su primer argumento (1).
En las capturas de pantalla siguientes se muestra el fundido en curso en cada plataforma:
Animaciones compuestas
Una animación compuesta es una combinación secuencial de animaciones y se puede crear con el await
operador , como se muestra en el ejemplo de código siguiente:
await image.TranslateTo (-100, 0, 1000); // Move image left
await image.TranslateTo (-100, -100, 1000); // Move image diagonally up and left
await image.TranslateTo (100, 100, 2000); // Move image diagonally down and right
await image.TranslateTo (0, 100, 1000); // Move image left
await image.TranslateTo (0, 0, 1000); // Move image up
En este ejemplo, Image
se traduce en 6 segundos (6000 milisegundos). La traducción de Image
utiliza cinco animaciones, con el await
operador que indica que cada animación se ejecuta secuencialmente. Por lo tanto, los métodos de animación posteriores se ejecutan una vez completado el método anterior.
Animaciones compuestas
Una animación compuesta es una combinación de animaciones donde dos o más animaciones se ejecutan simultáneamente. Las animaciones compuestas se pueden crear mezclando animaciones esperadas y no esperadas, como se muestra en el ejemplo de código siguiente:
image.RotateTo (360, 4000);
await image.ScaleTo (2, 2000);
await image.ScaleTo (1, 2000);
En este ejemplo, Image
se escala y gira simultáneamente más de 4 segundos (4000 milisegundos). El escalado de Image
utiliza dos animaciones secuenciales que se producen al mismo tiempo que la rotación. El RotateTo
método se ejecuta sin un await
operador y devuelve inmediatamente, con la primera ScaleTo
animación que comienza. El await
operador de la primera llamada al método ScaleTo
retrasa la segunda llamada al método ScaleTo
hasta que se haya completado la primera llamada al método ScaleTo
. En este momento, la RotateTo
animación se completa a mitad de camino y Image
se girará 180 grados. Durante los 2 segundos finales (2000 milisegundos), la segunda ScaleTo
animación y la RotateTo
animación se completan.
Ejecución simultánea de varios métodos asincrónicos
Los static
Task.WhenAny
métodos y Task.WhenAll
se usan para ejecutar varios métodos asincrónicos simultáneamente y, por tanto, se pueden usar para crear animaciones compuestas. Ambos métodos devuelven un Task
objeto y aceptan una colección de métodos que devuelven un Task
objeto. El Task.WhenAny
método se completa cuando cualquier método de su colección completa la ejecución, como se muestra en el ejemplo de código siguiente:
await Task.WhenAny<bool>
(
image.RotateTo (360, 4000),
image.ScaleTo (2, 2000)
);
await image.ScaleTo (1, 2000);
En este ejemplo, la Task.WhenAny
llamada al método contiene dos tareas. La primera tarea gira la imagen durante 4 segundos (4000 milisegundos) y la segunda tarea escala la imagen durante 2 segundos (2000 milisegundos). Cuando se completa la segunda tarea, se completa la llamada al Task.WhenAny
método . Sin embargo, aunque el RotateTo
método todavía se está ejecutando, el segundo ScaleTo
método puede comenzar.
El Task.WhenAll
método se completa cuando se han completado todos los métodos de su colección, como se muestra en el ejemplo de código siguiente:
// 10 minute animation
uint duration = 10 * 60 * 1000;
await Task.WhenAll (
image.RotateTo (307 * 360, duration),
image.RotateXTo (251 * 360, duration),
image.RotateYTo (199 * 360, duration)
);
En este ejemplo, la Task.WhenAll
llamada al método contiene tres tareas, cada una de las cuales se ejecuta más de 10 minutos. Cada Task
una realiza un número diferente de rotaciones de 360 grados: 307 rotaciones para RotateTo
, 251 rotaciones para RotateXTo
y 199 rotaciones para RotateYTo
. Estos valores son números primos, por lo tanto, garantizando que las rotaciones no están sincronizadas y, por tanto, no darán lugar a patrones repetitivos.
En las capturas de pantalla siguientes se muestran varias rotaciones en curso en cada plataforma:
Cancelación de animaciones
Una aplicación puede cancelar una o varias animaciones con una llamada al método de CancelAnimations
extensión, como se muestra en el ejemplo de código siguiente:
image.CancelAnimations();
Esto cancelará inmediatamente todas las animaciones que se ejecutan actualmente en la Image
instancia de .
Resumen
En este artículo se muestra cómo crear y cancelar animaciones mediante la ViewExtensions
clase . Esta clase proporciona métodos de extensión que se pueden usar para construir animaciones simples que giran, escalan, traducen y atenuan VisualElement
instancias.