Простые анимации в Xamarin.Forms
Класс ViewExtensions предоставляет методы расширения, которые можно использовать для создания простых анимаций. В этой статье показано создание и отмена анимаций с помощью класса ViewExtensions.
Класс ViewExtensions
предоставляет следующие методы расширения, которые можно использовать для создания простых анимаций:
CancelAnimations
отменяет любые анимации.FadeTo
анимируетOpacity
свойство объектаVisualElement
.RelScaleTo
применяет анимированное добавочное увеличение или уменьшение к свойствуScale
объектаVisualElement
.RotateTo
анимируетRotation
свойство объектаVisualElement
.RelRotateTo
применяет анимированное добавочное увеличение или уменьшение к свойствуRotation
объектаVisualElement
.RotateXTo
анимируетRotationX
свойство объектаVisualElement
.RotateYTo
анимируетRotationY
свойство объектаVisualElement
.ScaleTo
анимируетScale
свойство объектаVisualElement
.ScaleXTo
анимируетScaleX
свойство объектаVisualElement
.ScaleYTo
анимируетScaleY
свойство объектаVisualElement
.TranslateTo
анимируетTranslationX
свойстваTranslationY
и свойства объектаVisualElement
.
По умолчанию каждая анимация займет 250 миллисекундах. Однако при создании анимации можно указать длительность для каждой анимации.
Примечание.
Класс ViewExtensions
предоставляет LayoutTo
метод расширения. Однако этот метод предназначен для использования макетами для анимации переходов между состояниями макета, содержащими изменения размера и положения. Поэтому его следует использовать Layout
только подклассами.
Методы расширения анимации в ViewExtensions
классе являются асинхронными и возвращают Task<bool>
объект. Возвращаемое значение — это false
значение, если анимация завершается, и true
если анимация отменена. Поэтому методы анимации обычно следует использовать с await
оператором, что позволяет легко определить, когда анимация завершена. Кроме того, после завершения предыдущего метода можно создать последовательные анимации с последующими методами анимации. Дополнительные сведения см. в разделе "Составные анимации".
Если есть требование разрешить анимацию завершить в фоновом режиме, await
оператор может быть опущен. В этом сценарии методы расширения анимации быстро возвращаются после инициации анимации с анимацией, возникающей в фоновом режиме. Эту операцию можно использовать при создании составных анимаций. Дополнительные сведения см. в разделе "Составные анимации".
Дополнительные сведения об операторе см. в обзоре поддержки await
Async.
Отдельные анимации
Каждый метод расширения в этом ViewExtensions
методе реализует одну операцию анимации, которая постепенно изменяет свойство с одного значения на другое значение за период времени. В этом разделе рассматриваются все операции анимации.
Rotation
В следующем примере кода показано использование RotateTo
метода для анимации Rotation
свойства объекта Image
:
await image.RotateTo (360, 2000);
image.Rotation = 0;
Этот код анимирует Image
экземпляр путем поворота до 360 градусов в течение 2 секунд (2000 миллисекунд). Метод RotateTo
получает текущее Rotation
значение свойства для начала анимации, а затем поворачивается от этого значения к первому аргументу (360). После завершения анимации свойство изображения Rotation
сбрасывается до 0. Это гарантирует, что Rotation
свойство не остается в 360 после завершения анимации, что позволит предотвратить дополнительные повороты.
На следующих снимках экрана показана смена на каждой платформе:
Примечание.
RotateTo
Помимо метода, существуют также RotateXTo
и RotateYTo
методы, которые анимируют RotationX
и RotationY
свойства соответственно.
Относительная смена
В следующем примере кода показано использование RelRotateTo
метода для добавочного увеличения или уменьшения Rotation
свойства объекта Image
:
await image.RelRotateTo (360, 2000);
Этот код анимирует Image
экземпляр, вращая 360 градусов с начальной позиции более 2 секунд (2000 миллисекунд). Метод RelRotateTo
получает текущее Rotation
значение свойства для начала анимации, а затем поворачивается от этого значения к значению плюс его первый аргумент (360). Это гарантирует, что каждая анимация всегда будет поворотом в 360 градусов с начальной позиции. Таким образом, если при выполнении анимации вызывается новая анимация, она начинается с текущей позиции и может заканчиваться на позиции, которая не является шагом 360 градусов.
На следующих снимках экрана показан относительный поворот на каждой платформе:
Масштабирование
В следующем примере кода показано использование ScaleTo
метода для анимации Scale
свойства объекта Image
:
await image.ScaleTo (2, 2000);
Этот код анимирует Image
экземпляр, масштабируя до двухкратного размера в течение 2 секунд (2000 миллисекунд). Метод ScaleTo
получает текущее Scale
значение свойства (значение по умолчанию 1) для начала анимации, а затем масштабируется от этого значения до первого аргумента (2). Это влияет на расширение размера изображения до дважды его размера.
На следующих снимках экрана показано, как масштабироваться на каждой платформе:
Примечание.
ScaleTo
Помимо метода, существуют также ScaleXTo
и ScaleYTo
методы, которые анимируют ScaleX
и ScaleY
свойства соответственно.
Относительное масштабирование
В следующем примере кода показано использование RelScaleTo
метода для анимации Scale
свойства объекта Image
:
await image.RelScaleTo (2, 2000);
Этот код анимирует Image
экземпляр, масштабируя до двухкратного размера в течение 2 секунд (2000 миллисекунд). Метод RelScaleTo
получает текущее Scale
значение свойства для начала анимации, а затем масштабируется от этого значения до значения плюс его первый аргумент (2). Это гарантирует, что каждая анимация всегда будет масштабированием 2 из начальной позиции.
Масштабирование и поворот с помощью привязок
AnchorY
Свойства AnchorX
задают центр масштабирования или поворота для Rotation
свойств и Scale
свойств. Поэтому их значения также влияют на RotateTo
методы и ScaleTo
методы.
Image
Учитывая, что он был размещен в центре макета, следующий пример кода демонстрирует поворот изображения вокруг центра макета, задав его AnchorY
свойство:
double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
image.AnchorY = radius / image.Height;
await image.RotateTo(360, 2000);
Для поворота Image
экземпляра вокруг центра макета AnchorX
AnchorY
необходимо задать значения, которые имеют значение относительно ширины и высоты Image
. В этом примере центр определяется в центре Image
макета, поэтому значение по умолчанию AnchorX
0,5 не требует изменения. AnchorY
Однако свойство переопределено, чтобы быть значением из верхней части Image
до центра макета. Это обеспечивает Image
полную смену 360 градусов вокруг центра макета, как показано на следующих снимках экрана:
Перевод текста
В следующем примере кода показано использование TranslateTo
метода для анимации TranslationX
и TranslationY
свойств объекта Image
:
await image.TranslateTo (-100, -100, 1000);
Этот код анимирует Image
экземпляр путем преобразования его горизонтально и вертикально более 1 секунды (1000 миллисекунд). Метод TranslateTo
одновременно преобразует изображение в 100 пикселей слева и 100 пикселей вверх. Это связано с тем, что первый и второй аргументы являются отрицательными числами. Предоставление положительных чисел приведет к переводу изображения вправо и вниз.
На следующих снимках экрана показано, как выполняется перевод на каждой платформе:
Примечание.
Если элемент изначально выложен с экрана, а затем переведен на экран, после перевода входного макета элемента остается вне экрана, и пользователь не может взаимодействовать с ним. Поэтому рекомендуется, чтобы представление должно быть изложено в окончательной позиции, а затем все необходимые переводы.
Исчезание
В следующем примере кода показано использование FadeTo
метода для анимации Opacity
свойства объекта Image
:
image.Opacity = 0;
await image.FadeTo (1, 4000);
Этот код анимирует Image
экземпляр, увядая его в течение 4 секунд (4000 миллисекунд). Метод FadeTo
получает текущее Opacity
значение свойства для начала анимации, а затем исчезает из этого значения до первого аргумента (1).
На следующих снимках экрана показано, что на каждой платформе выполняется затухание.
Составные анимации
Составная анимация — это последовательное сочетание анимаций и может быть создано с await
помощью оператора, как показано в следующем примере кода:
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
В этом примере Image
преобразуется более 6 секунд (6000 миллисекунд). Перевод Image
пяти анимаций с await
оператором, указывающим, что каждая анимация выполняется последовательно. Поэтому последующие методы анимации выполняются после завершения предыдущего метода.
Составные анимации
Составная анимация — это сочетание анимаций, в которых одновременно выполняются две или несколько анимаций. Составные анимации можно создать путем смешивания ожидаемых и не ожидаемых анимаций, как показано в следующем примере кода:
image.RotateTo (360, 4000);
await image.ScaleTo (2, 2000);
await image.ScaleTo (1, 2000);
В этом примере Image
масштабируется и одновременно поворачивается в течение 4 секунд (4000 миллисекунд). Масштабирование Image
двух последовательных анимаций, происходящих одновременно с поворотом. Метод RotateTo
выполняется без await
оператора и возвращается немедленно с первой ScaleTo
анимацией, а затем начинается. Оператор await
первого ScaleTo
вызова метода задерживает второй ScaleTo
вызов метода до завершения первого ScaleTo
вызова метода. На этом этапе анимация RotateTo
завершена на полпути, и Image
будет поворачиваться 180 градусов. В течение последних 2 секунд (2000 миллисекунд), вторая ScaleTo
анимация и анимация RotateTo
оба завершены.
Одновременное выполнение нескольких асинхронных методов
Task.WhenAll
Методы static
Task.WhenAny
используются для одновременного выполнения нескольких асинхронных методов и поэтому можно использовать для создания составных анимаций. Оба метода возвращают Task
объект и принимают коллекцию методов, которые возвращают Task
объект. Метод Task.WhenAny
завершается, когда любой метод в коллекции завершает выполнение, как показано в следующем примере кода:
await Task.WhenAny<bool>
(
image.RotateTo (360, 4000),
image.ScaleTo (2, 2000)
);
await image.ScaleTo (1, 2000);
В этом примере Task.WhenAny
вызов метода содержит две задачи. Первая задача поворачивает изображение в течение 4 секунд (4000 миллисекунд), а вторая задача масштабирует изображение в течение 2 секунд (2000 миллисекунд). После завершения Task.WhenAny
второй задачи вызов метода завершается. Однако, несмотря на то, что RotateTo
метод по-прежнему запущен, второй ScaleTo
метод может начаться.
Метод Task.WhenAll
завершается, когда все методы в коллекции завершены, как показано в следующем примере кода:
// 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)
);
В этом примере Task.WhenAll
вызов метода содержит три задачи, каждая из которых выполняется более 10 минут. Каждая Task
из них составляет 360 градусов поворотов — 307 поворотов для , 251 поворотов для RotateTo
RotateXTo
и 199 поворотов для RotateYTo
. Эти значения являются простыми числами, поэтому гарантируя, что повороты не синхронизированы и поэтому не приводят к повторяющимся шаблонам.
На следующих снимках экрана показано несколько поворотов на каждой платформе:
Отмена анимаций
Приложение может отменить одну или несколько анимаций с вызовом CancelAnimations
метода расширения, как показано в следующем примере кода:
image.CancelAnimations();
Это немедленно отменит все анимации, которые в настоящее время выполняются в экземпляре Image
.
Итоги
В этой статье показано создание и отмена анимаций с помощью ViewExtensions
класса. Этот класс предоставляет методы расширения, которые можно использовать для создания простых анимаций, вращающихся, масштабируемых, переводных и исчезающих VisualElement
экземпляров.