Animações simples em Xamarin.Forms
A classe ViewExtensions fornece métodos de extensão que podem ser usados para construir animações simples. Este artigo demonstra a criação e o cancelamento de animações usando a classe ViewExtensions.
A ViewExtensions
classe fornece os seguintes métodos de extensão que podem ser usados para criar animações simples:
CancelAnimations
cancela todas as animações.FadeTo
anima aOpacity
propriedade de umVisualElement
arquivo .RelScaleTo
Aplica um aumento ou uma diminuição incremental animada àScale
propriedade de umVisualElement
arquivo .RotateTo
anima aRotation
propriedade de umVisualElement
arquivo .RelRotateTo
Aplica um aumento ou uma diminuição incremental animada àRotation
propriedade de umVisualElement
arquivo .RotateXTo
anima aRotationX
propriedade de umVisualElement
arquivo .RotateYTo
anima aRotationY
propriedade de umVisualElement
arquivo .ScaleTo
anima aScale
propriedade de umVisualElement
arquivo .ScaleXTo
anima aScaleX
propriedade de umVisualElement
arquivo .ScaleYTo
anima aScaleY
propriedade de umVisualElement
arquivo .TranslateTo
anima asTranslationX
propriedades eTranslationY
de umVisualElement
arquivo .
Por padrão, cada animação levará 250 milissegundos. No entanto, uma duração para cada animação pode ser especificada ao criar a animação.
Observação
A ViewExtensions
classe fornece um método de LayoutTo
extensão. No entanto, esse método destina-se a ser usado por layouts para animar transições entre estados de layout que contêm alterações de tamanho e posição. Portanto, ele só deve ser usado por Layout
subclasses.
Os métodos de extensão de animação na classe são todos assíncronos ViewExtensions
e retornam um Task<bool>
objeto. O valor de retorno é false
se a animação for concluída e true
se a animação for cancelada. Portanto, os métodos de animação normalmente devem ser usados com o operador, o await
que torna possível determinar facilmente quando uma animação foi concluída. Além disso, torna-se possível criar animações sequenciais com métodos de animação subsequentes em execução após a conclusão do método anterior. Para obter mais informações, consulte Animações compostas.
Se houver um requisito para permitir que uma animação seja concluída em segundo plano, o await
operador poderá ser omitido. Nesse cenário, os métodos de extensão de animação retornarão rapidamente depois de iniciar a animação, com a animação ocorrendo em segundo plano. Essa operação pode ser aproveitada ao criar animações compostas. Para obter mais informações, consulte Animações compostas.
Para obter mais informações sobre o operador, consulte Visão geral do suporte assíncronoawait
.
Animações individuais
Cada método de extensão no implementa ViewExtensions
uma única operação de animação que altera progressivamente uma propriedade de um valor para outro valor ao longo de um período de tempo. Esta seção explora cada operação de animação.
Rotação
O exemplo de código a seguir demonstra o uso do RotateTo
método para animar a Rotation
propriedade de um Image
:
await image.RotateTo (360, 2000);
image.Rotation = 0;
Esse código anima a Image
instância girando até 360 graus em 2 segundos (2000 milissegundos). O RotateTo
método obtém o valor da propriedade atual Rotation
para o início da animação e, em seguida, gira desse valor para seu primeiro argumento (360). Quando a animação estiver concluída, a propriedade da Rotation
imagem será redefinida para 0. Isso garante que a Rotation
propriedade não permaneça em 360 após a conclusão da animação, o que impediria rotações adicionais.
As capturas de tela a seguir mostram a rotação em andamento em cada plataforma:
Observação
Além do RotateTo
método, existem também RotateXTo
e RotateYTo
métodos que animam as RotationX
e RotationY
propriedades, respectivamente.
Rotação Relativa
O exemplo de código a seguir demonstra o uso do RelRotateTo
método para incrementalmente aumentar ou diminuir a Rotation
propriedade de um Image
:
await image.RelRotateTo (360, 2000);
Esse código anima a Image
instância girando 360 graus de sua posição inicial em 2 segundos (2000 milissegundos). O RelRotateTo
método obtém o valor da propriedade atual Rotation
para o início da animação e, em seguida, gira desse valor para o valor mais seu primeiro argumento (360). Isso garante que cada animação será sempre uma rotação de 360 graus a partir da posição inicial. Portanto, se uma nova animação for invocada enquanto uma animação já estiver em andamento, ela começará a partir da posição atual e poderá terminar em uma posição que não seja um incremento de 360 graus.
As capturas de tela a seguir mostram a rotação relativa em andamento em cada plataforma:
Scaling
O exemplo de código a seguir demonstra o uso do ScaleTo
método para animar a Scale
propriedade de um Image
:
await image.ScaleTo (2, 2000);
Esse código anima a Image
instância dimensionando até o dobro de seu tamanho em 2 segundos (2000 milissegundos). O ScaleTo
método obtém o valor da propriedade atual Scale
(valor padrão de 1) para o início da animação e, em seguida, dimensiona desse valor para seu primeiro argumento (2). Isso tem o efeito de expandir o tamanho da imagem para o dobro de seu tamanho.
As capturas de tela a seguir mostram o dimensionamento em andamento em cada plataforma:
Observação
Além do ScaleTo
método, existem também ScaleXTo
e ScaleYTo
métodos que animam as ScaleX
e ScaleY
propriedades, respectivamente.
Dimensionamento relativo
O exemplo de código a seguir demonstra o uso do RelScaleTo
método para animar a Scale
propriedade de um Image
:
await image.RelScaleTo (2, 2000);
Esse código anima a Image
instância dimensionando até o dobro de seu tamanho em 2 segundos (2000 milissegundos). O RelScaleTo
método obtém o valor da propriedade atual Scale
para o início da animação e, em seguida, escala desse valor para o valor mais seu primeiro argumento (2). Isso garante que cada animação sempre será uma escala de 2 a partir da posição inicial.
Dimensionamento e Rotação com Âncoras
As AnchorX
propriedades e AnchorY
definem o centro de dimensionamento ou rotação para as Rotation
propriedades e Scale
. Portanto, seus valores também afetam os RotateTo
e ScaleTo
métodos.
Dado um Image
que foi colocado no centro de um layout, o exemplo de código a seguir demonstra girar a imagem em torno do centro do layout definindo sua AnchorY
propriedade:
double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
image.AnchorY = radius / image.Height;
await image.RotateTo(360, 2000);
Para girar a Image
ocorrência em torno do centro do layout, as AnchorX
propriedades e AnchorY
devem ser definidas como valores relativos à largura e altura do Image
. Neste exemplo, o centro do Image
é definido para estar no centro do layout e, portanto, o valor padrão AnchorX
de 0,5 não requer alteração. No entanto, a AnchorY
propriedade é redefinida para ser um valor da parte superior do Image
ponto central do layout. Isso garante que o Image
faça uma rotação completa de 360 graus em torno do ponto central do layout, conforme mostrado nas seguintes capturas de tela:
Tradução
O exemplo de código a seguir demonstra o uso do TranslateTo
método para animar as TranslationX
propriedades e TranslationY
de um Image
:
await image.TranslateTo (-100, -100, 1000);
Esse código anima a instância traduzindo-a Image
horizontal e verticalmente em 1 segundo (1000 milissegundos). O TranslateTo
método traduz simultaneamente a imagem 100 pixels para a esquerda e 100 pixels para cima. Isso porque o primeiro e o segundo argumentos são ambos números negativos. Fornecer números positivos traduziria a imagem para a direita e para baixo.
As capturas de tela a seguir mostram a tradução em andamento em cada plataforma:
Observação
Se um elemento for inicialmente colocado fora da tela e, em seguida, traduzido para a tela, após a tradução, o layout de entrada do elemento permanecerá fora da tela e o usuário não poderá interagir com ele. Portanto, recomenda-se que uma visão seja apresentada em sua posição final e, em seguida, quaisquer traduções necessárias sejam realizadas.
Esmaecimento
O exemplo de código a seguir demonstra o uso do FadeTo
método para animar a Opacity
propriedade de um Image
:
image.Opacity = 0;
await image.FadeTo (1, 4000);
Esse código anima a instância desvanecendo-a Image
em mais de 4 segundos (4000 milissegundos). O FadeTo
método obtém o valor da propriedade atual Opacity
para o início da animação e, em seguida, desaparece desse valor para seu primeiro argumento (1).
As capturas de tela a seguir mostram o fade em andamento em cada plataforma:
Animações compostas
Uma animação composta é uma combinação sequencial de animações e pode ser criada com o await
operador, conforme demonstrado no exemplo de código a seguir:
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
Neste exemplo, o é traduzido Image
em 6 segundos (6000 milissegundos). A tradução do Image
usa cinco animações, com o await
operador indicando que cada animação é executada sequencialmente. Portanto, os métodos de animação subsequentes são executados após a conclusão do método anterior.
Animações compostas
Uma animação composta é uma combinação de animações em que duas ou mais animações são executadas simultaneamente. As animações compostas podem ser criadas misturando animações aguardadas e não aguardadas, conforme demonstrado no exemplo de código a seguir:
image.RotateTo (360, 4000);
await image.ScaleTo (2, 2000);
await image.ScaleTo (1, 2000);
Neste exemplo, o é dimensionado e girado simultaneamente ao longo de Image
4 segundos (4000 milissegundos). O dimensionamento do Image
usa duas animações sequenciais que ocorrem ao mesmo tempo que a rotação. O RotateTo
método é executado sem um await
operador e retorna imediatamente, com a primeira ScaleTo
animação em seguida, começando. O await
operador na primeira ScaleTo
chamada de método atrasa a segunda ScaleTo
chamada de método até que a primeira ScaleTo
chamada de método seja concluída. Neste ponto, a animação está na metade do RotateTo
caminho e o será girado Image
180 graus. Durante os 2 segundos finais (2000 milissegundos), a segunda ScaleTo
animação e a RotateTo
animação são concluídas.
Executando vários métodos assíncronos simultaneamente
Os static
Task.WhenAny
métodos e Task.WhenAll
são usados para executar vários métodos assíncronos simultaneamente e, portanto, podem ser usados para criar animações compostas. Ambos os métodos retornam um Task
objeto e aceitam uma coleção de métodos que cada um retorna um Task
objeto. O Task.WhenAny
método é concluído quando qualquer método em sua coleção conclui a execução, conforme demonstrado no exemplo de código a seguir:
await Task.WhenAny<bool>
(
image.RotateTo (360, 4000),
image.ScaleTo (2, 2000)
);
await image.ScaleTo (1, 2000);
Neste exemplo, a chamada de Task.WhenAny
método contém duas tarefas. A primeira tarefa gira a imagem em 4 segundos (4000 milissegundos) e a segunda tarefa escala a imagem em 2 segundos (2000 milissegundos). Quando a segunda tarefa for concluída, a chamada de Task.WhenAny
método será concluída. No entanto, mesmo que o RotateTo
método ainda esteja em execução, o segundo ScaleTo
método pode começar.
O Task.WhenAll
método é concluído quando todos os métodos em sua coleção foram concluídos, conforme demonstrado no exemplo de código a seguir:
// 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)
);
Neste exemplo, a Task.WhenAll
chamada de método contém três tarefas, cada uma das quais é executada ao longo de 10 minutos. Cada Task
um faz um número diferente de rotações de 360 graus – 307 rotações para RotateTo
, 251 rotações para RotateXTo
, e 199 rotações para RotateYTo
. Esses valores são números primos, portanto, garantindo que as rotações não sejam sincronizadas e, portanto, não resultem em padrões repetitivos.
As capturas de tela a seguir mostram as várias rotações em andamento em cada plataforma:
Cancelando animações
Um aplicativo pode cancelar uma ou mais animações com uma chamada para o CancelAnimations
método de extensão, conforme demonstrado no exemplo de código a seguir:
image.CancelAnimations();
Isso cancelará imediatamente todas as animações que estão sendo executadas na Image
instância.
Resumo
Este artigo demonstrou a criação e o cancelamento de animações usando a ViewExtensions
classe. Essa classe fornece métodos de VisualElement
extensão que podem ser usados para construir animações simples que giram, dimensionam, traduzem e desvanecem instâncias.