Partilhar via


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:

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 deve 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 retornado será 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 sendo executados 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 após o início da 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 únicas

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 durante 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 for concluída, a propriedade da Rotation imagem será redefinida como 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:

Animação de rotação

Observação

Além do RotateTo método, existem também RotateXTo métodos e RotateYTo que animam as RotationX propriedades and RotationY , respectivamente.

Rotação relativa

O exemplo de código a seguir demonstra o uso do RelRotateTo método para aumentar ou diminuir incrementalmente 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 ao longo de 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 sempre tenha 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á na 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:

Animação de rotação relativa

Dimensionamento

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 escalando 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, é dimensionado desse valor para seu primeiro argumento (2). Isso tem o efeito de expandir o tamanho da imagem para o dobro do seu tamanho.

As capturas de tela a seguir mostram o dimensionamento em andamento em cada plataforma:

Animação de dimensionamento

Observação

Além do ScaleTo método, existem também ScaleXTo métodos e ScaleYTo que animam as ScaleX propriedades and ScaleY , respectivamente.

Escala relativa

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 escalando 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 tenha uma escala de 2 a partir da posição inicial.

Dimensionamento e rotação com âncoras

As AnchorX propriedades and AnchorY definem o centro de dimensionamento ou rotação para as Rotation propriedades and Scale . Portanto, seus valores também afetam os RotateTo métodos e ScaleTo .

Dado um Image que foi colocado no centro de um layout, o exemplo de código a seguir demonstra a rotação da 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 instâ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 como estando no centro do layout e, portanto, o valor padrão AnchorX de 0,5 não precisa ser alterado. 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 capturas de tela a seguir:

Animação de rotação com âncoras

Tradução

O exemplo de código a seguir demonstra o uso do TranslateTo método para animar as TranslationX propriedades and TranslationY de um Image:

await image.TranslateTo (-100, -100, 1000);

Esse código anima a Image instância convertendo-a 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 ocorre porque o primeiro e o segundo argumentos são 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:

Animação de tradução

Observação

Se um elemento for inicialmente disposto 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, é recomendável que uma exibição seja apresentada em sua posição final e, em seguida, todas as traduções necessárias sejam executadas.

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 Image instância esmaecendo-a 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ção de desvanecimento

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 Image é convertido 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 esperadas e não esperadas, 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 Image é dimensionado e girado simultaneamente em 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 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 RotateTo animação está na metade do caminho e será girada 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 and 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 retornam 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 dimensiona a imagem em 2 segundos (2000 milissegundos). Quando a segunda tarefa é concluída, a chamada do Task.WhenAny método é 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 são 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 chamada de Task.WhenAll método contém três tarefas, cada uma das quais é executada em 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, garantindo assim 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:

Animação Composta

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 no momento.

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 esmaecem instâncias.