第二十二章:动画(十五)

简介: 深入动画在第一次遇到时,完整的Xamarin.Forms动画系统可能会有点混乱。 让我们从可用于定义动画的三个公共类的全局视图开始。整理课程除了Easing类之外,Xamarin.Forms动画系统还包含三个公共类。

深入动画

在第一次遇到时,完整的Xamarin.Forms动画系统可能会有点混乱。 让我们从可用于定义动画的三个公共类的全局视图开始。
整理课程
除了Easing类之外,Xamarin.Forms动画系统还包含三个公共类。 在这里,它们按层次顺序从高级别到低级别:
ViewExtensions类
这是你已经看过的课程。 ViewExtensions是一个静态类,它包含VisualElement的几个扩展方法,它是View和Page的父类:

  • TranslateTo为TranslationX和TranslationY属性设置动画
  • ScaleTo为Scale属性设置动画
  • ResScaleTo将动画增量增加或减少应用于Scale属性
  • RotateTo为“旋转”属性设置动画
  • RelRotateTo将动画增量增加或减少应用于“旋转”属性
  • RotateXTo为RotationX属性设置动画
  • RotateYTo为RotationY属性设置动画
  • FadeTo为Opacity属性设置动画
  • Layout通过调用Layout方法为get-only Bounds属性设置动画

如您所见,前七种方法以转换属性为目标。 这些属性不会导致在布局中如何感知元素的任何更改。 虽然动画视图可以移动,更改大小和旋转,但页面上的其他任何视图都不会受到影响,除非可能被新位置或大小遮挡。
FadeTo动画仅更改Opacity属性,因此也不会导致布局更改。
正如您所见,LayoutTo动画有点不同。 参数是一个Rectangle值,该方法实质上覆盖了元素的父Layout或Layout 对象分配给视图的位置和大小。 LayoutTo对于为AbsoluteLayout的子项设置动画非常有用,因为您可以使用相同的Rectangle对象调用AbsoluteLayout.SetLayoutBounds
动画完成后。 在第26章中,您将学习如何在从Layout 派生的类中使用LayoutTo。
这些都是返回Task 的异步方法。 如果动画被取消,则布尔返回值为true;如果动画完成,则返回false。
此外,ViewExtensions还包含一个静态ViewExtensions.CancelAnimations方法(不是扩展方法),该方法具有VisualElement类型的单个参数。 此方法取消在该VisualElement对象上使用此类启动的所有动画。
ViewExtensions中的所有扩展方法都可以通过创建一个或多个Animation对象然后调用该Animation类定义的Commit方法来工作。
动画类
Animation类有两个构造函数:一个无参数构造函数和另一个带有五个参数的构造函数,尽管只需要一个参数:

public Animation (Action<double> callback, 
                  double start = 0.0f, 
                  double end = 1.0f, 
                  Easing easing = null, 
                  Action finished = null)

这定义了一个double值的动画,它从start开始到结束。 通常,这两个参数的默认值分别为0和1。 动画值作为参数传递给回调方法,通常将其命名为t或progress。 回调可以使用此值执行任何操作,但通常用于更改属性的值。 如果target属性的类型为double,则start和end值可以直接定义动画属性的开始值和结束值。
动画实现IEnumerable接口。 它可以维护一组子动画,然后可以统一启动并保持同步。 要允许程序将项添加到此集合,Animation定义了四种方法:

  • Add
  • Insert
  • WithConcurrent (两个版本)

这些都基本相同,因为它们都将子动画对象添加到由Animation维护的内部集合中。 你很快就会看到例子。
启动动画(可能包括或不包括子动画)需要调用Commit方法。 Commit方法指定动画的持续时间,还包括两个回调:

animation.Commit(IAnimatable owner,
                 string name,
                 uint rate = 16,
                 uint length = 250,
                 Easing easing = null,
                 Action<double, bool> finished = null,
                 Func<bool> repeat = null);

注意第一个参数是IAnimatable。 IAnimatable接口只定义了两个方法,名为BatchBegin和BatchCommit。 实现IAnimatable的唯一类是VisualElement,它是与ViewExtensions方法关联的类。
name参数标识动画。 您可以使用AnimationExtensions类(即将出现)中的方法来确定该名称的动画是否正在运行或取消它。 您不需要为正在运行的每个动画使用唯一的名称,但如果您在同一个可视对象上进行多个重叠的Commit调用,那么这些名称应该是唯一的。
理论上,rate参数表示每次调用Animation构造函数中定义的回调方法之间的毫秒数。 对于每秒60帧的动画速度,它设置为16,但更改它没有任何效果。
重复回调允许重复动画。 它在动画结束时调用,如果回调返回true,则表示应该重复动画。 正如您将看到的,它适用于某些配置但不适用于其他配置。
Animation类中的Commit方法通过调用AnimationExtensions类中的Animate方法来工作。
AnimationExtensions类
与ViewExtensions一样,AnimationExtentions是一个静态类,主要包含扩展方法。 但是,虽然ViewExtensions方法中的第一个参数是VisualElement,但AnimationExtensions方法中的第一个参数是IAnimatable,以与Animation类中的Commit方法保持一致。
AnimationExtensions使用回调和其他信息定义Animate方法的几个重载。 最广泛的Animate版本是这种通用方法:

public static void Animate<T>(this IAnimatable self,
                              string name,
                              Func<double, T> transform,
                              Action<T> callback,
                              uint rate = 16,
                              uint length = 250,
                              Easing easing = null,
                              Action<T, bool> finished = null,
                              Func<bool> repeat = null);

从某种意义上说,这是您需要的唯一动画方法。 到目前为止,许多这些参数应该是可识别的。 但请注意可以帮助构建动画逻辑的转换方法
目标属性不是double类型。
例如,假设您要为Color类型的属性设置动画。 首先编写一个小变换方法,接受从0到1(通常命名为t或progress)的double参数,并返回与该值对应的Color值。 回调方法获取Color值,然后可以将其设置为特定对象的特定属性。 您将在本章末尾看到这个精确的应用程序。
AnimationExtensions类中的其他公共方法是AnimationIsRunning,用于确定特定VisualElement实例上的特定动画是否正在运行,以及AbortAnimation是否取消动画。 两者都是IAnimatable的扩展方法,并且要求名称与传递给Animate方法的名称或Animation的Commit方法一致。

目录
相关文章
|
JavaScript Android开发
第二十二章:动画(二十一)
使用AnimationExtensions为什么ViewExtensions不包含ColorTo动画? 这种方法没有你最初假设的那么明显有三个可能的原因:首先,VisualElement定义的唯一Color属性是BackgroundColor,但通常不是要设置动画的Color属性。
567 0
|
JavaScript Android开发
第二十二章:动画(二十)
实现贝塞尔动画一些图形系统实现动画,该动画沿着贝塞尔曲线移动视觉对象,甚至(可选地)旋转视觉对象,使其保持与曲线相切。Bezier曲线以法国工程师兼数学家PierreBézier的名字命名,他在雷诺工作期间开发了用于汽车车身交互式计算机辅助设计的曲线。
652 0
|
JavaScript Android开发
第二十二章:动画(十九)
更多你自己的等待方法之前,您已经了解了如何将TaskCompletionSource与Device.StartTimer一起使用来编写自己的异步动画方法。 您还可以将TaskCompletionSource与Animation类结合使用,编写自己的异步动画方法,类似于ViewExtensions类中的方法。
666 0
|
Android开发
第二十二章:动画(十七)
子动画ConcurrentAnimations中的前两个示例是单个动画。 Animation类还支持子动画,这就是标记为“Animation 3”的Button的处理程序。 它首先使用无参数构造函数创建父动画对象。
705 0
|
Android开发
第二十二章:动画(十八)
超越高级动画方法你到目前为止看到的ConcurrentAnimations中的例子仅限于Scale和Rotate属性的动画,因此它们没有显示任何你无法做的事情。ViewExtensions类中的方法。
728 0
|
JavaScript Android开发
第二十二章:动画(十六)
使用Animation类让我们对Animation类进行一些实验。 这涉及实例化Animation类型的对象,然后调用Commit,它实际上开始动画。 Commit方法不返回Task对象; 相反,Animation类完全通过回调提供通知。
723 0
|
JavaScript Android开发
第二十二章:动画(十四)
你自己的等待动画在本章的下一节中,您将看到Xamarin.Forms实现的基础动画基础结构。这些底层方法允许您定义自己的动画函数,这些函数返回Task对象,并且可以与await一起使用。在第20章“异步和文件I / O”中,您了解了如何使用静态Task.Run方法创建执行的辅助线程,以执行像Mandelbrot计算这样的密集后台作业。
737 0
|
JavaScript Android开发 iOS开发
第二十二章:动画(十二)
永远的动画在入口动画的相反极端是永远的动画。 应用程序可以实现“永远”或至少在程序结束之前进行的动画。 这种动画的唯一目的通常是展示动画系统的功能,但最好是以令人愉快或有趣的方式。第一个示例称为FadingTextAnimation,并使用FadeTo淡入和淡出两个Label元素。
663 0
|
JavaScript Android开发
第二十二章:动画(十一)
入口动画实际编程中的一种常见类型的动画是在页面首次可见时发生的。 页面上的各种元素可以在进入最终状态之前进行简要动画处理。 这通常被称为入口动画,可能涉及: 翻译,将元素移动到最终位置。 缩放,将元素放大或缩小到最终尺寸。
879 0
|
JavaScript Android开发
第二十二章:动画(十)
你自己的缓和功能您可以轻松制作自己的缓动功能。所需要的只是一个类型为Func 的方法,它是一个带有double参数和double返回值的函数。这是一个传递函数:它应该为0的参数返回0,并且对于1的参数应该返回1.但是在这两个值之间,任何事情都会发生。
599 0