Xamarin.Forms 用户界面——动画——自定义动画

自定义动画

PDF用于离线使用
示例代码:
相关API:

让我们知道你对此的感受

最后更新:2016年7月

Animation类是所有Xamarin.Forms动画的构建块,ViewExtensions类中的扩展方法创建一个或多个Animation对象。本文演示如何使用Animation类创建和取消动画,同步多个动画,并创建自定义动画,使动画的属性不被现有的动画方法动画化。

概观

创建Animation对象时必须指定多个参数,包括动画属性的开始和结束值以及更改属性值的回调。一个Animation物体也能保持可运行和同步的儿童动画的集合。有关更多信息,请参阅儿童动画

Animation通过调用该Commit方法,可以运行使用该类创建的动画(可能包含或不包含子动画)。此方法指定动画的持续时间,以及其他项目之间的控制是否重复动画的回调。

创建动画

在创建Animation对象时,通常需要至少三个参数,如下面的代码示例所示:

var animation = new Animation (v => image.Scale = v, 1, 2);

该代码将一个实例Scale属性的动画Image从值1定义为值2.由Xamarin.Forms派生的动画值被传递给指定为第一个参数的回调,用于更改Scale物业的价值。

通过调用该Commit方法开始动画,如下面的代码示例所示:

animation.Commit (this, "SimpleAnimation", 16, 2000, Easing.Linear, (v, c) => image.Scale = 1, () => true);

请注意,该Commit方法不返回Task对象。相反,通过回调方法提供通知。

以下参数在Commit方法中指定:

  • 第一个参数(owner)标识动画的所有者。这可以是应用动画的视觉元素,或其他视觉元素,如页面。
  • 第二个参数(name)用一个名称标识动画。该名称与所有者结合以唯一标识动画。然后可以使用该唯一标识来确定动画是正在运行(AnimationIsRunning)还是取消它(AbortAnimation)。
  • 第三个参数(rate)表示在Animation构造函数中定义的每个调用回调方法之间的毫秒数
  • 第四个参数(length)表示动画的持续时间,以毫秒为单位。
  • 第五个参数(简化)定义了动画中要使用的缓动函数。或者,可以将缓动函数指定为Animation构造函数的参数。有关宽松功能的更多信息,请参阅缓动功能
  • 第六个参数(finished)是一个回调,当动画完成时将执行。这个回调函数有两个参数,第一个参数表示一个最终值,第二个参数bool设置为true动画被取消。或者,完成的回调可以被指定为Animation构造函数的参数。但是,使用单个动画,如果在构造函数和方法中都指定了完成的回调,则只会执行该方法中指定的回调。AnimationCommitCommit
  • 第七个参数(重复)是一个回调,允许重复动画。它在动画结束时被调用,返回true表示应该重复动画。

整体效果是使用缓动功能创建一个将Scale属性Image从1增加到2秒(2000毫秒)的动画Linear。每次动画完成后,其Scale属性将重置为1,并重复动画。

可以通过Animation为每个动画创建一个对象,然后Commit在每个动画上调用该方法来构建彼此独立运行的并行动画。

子动画

Animation班还支持子动画,这涉及到创建Animation到其他对象Animation添加的对象。这样可以运行和同步一系列动画。以下代码示例演示如何创建和运行子动画:

var parentAnimation = new Animation ();
var scaleUpAnimation = new Animation (v => image.Scale = v, 1, 2, Easing.SpringIn);
var rotateAnimation = new Animation (v => image.Rotation = v, 0, 360);
var scaleDownAnimation = new Animation (v => image.Scale = v, 2, 1, Easing.SpringOut);

parentAnimation.Add (0, 0.5, scaleUpAnimation);
parentAnimation.Add (0, 1, rotateAnimation);
parentAnimation.Add (0.5, 1, scaleDownAnimation);

parentAnimation.Commit (this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState (true, false));

或者,代码示例可以更简洁地写出,如下面的代码示例所示:

new Animation {
    { 0, 0.5, new Animation (v => image.Scale = v, 1, 2) },
    { 0, 1, new Animation (v => image.Rotation = v, 0, 360) },
    { 0.5, 1, new Animation (v => image.Scale = v, 2, 1) }
    }.Commit (this, "ChildAnimations", 16, 4000, null, (v, c) => SetIsEnabledButtonState (true, false));

在两个代码示例中,Animation创建一个父对象,Animation然后添加其他对象。该Add方法的前两个参数指定何时开始和完成子动画。参数值必须在0和1之间,并且表示父动画中指定的子动画将处于活动状态的相对周期。因此,在这个例子scaleUpAnimation中,动画的前半部分scaleDownAnimation将被激活,动画的下半部分rotateAnimation将被激活,并且整个持续时间将被激活。

整体效果是动画发生超过4秒(4000毫秒)。在scaleUpAnimation所述动画Scale属性从1到2,经2秒。所述scaleDownAnimation然后动画的Scale属性从2到1,经2秒。虽然这两种缩放动画正在发生,rotateAnimation动画的Rotation属性从0到360,超过4秒。请注意,缩放动画也使用缓动功能。在SpringIn宽松的功能使Image最初越来越大前收缩和SpringOut放松功能使Image变得比实现全面动画结束它的实际尺寸。

Animation使用子动画 的对象之间存在许多不同之处:

  • 当使用子动画时,子动画上的完成的回调指示孩子何时完成,并且传递给该方法的完成的回调Commit指示整个动画何时完成。
  • 当使用子动画时,true从方法上的重复回调返回Commit不会导致动画重复,但动画将继续运行而没有新值。
  • 当在Commit方法中包含一个缓动函数,并且缓动函数返回大于1的值时,动画将被终止。如果缓动函数返回小于0的值,则该值被钳制为0.要使用返回小于0或大于1的值的缓动函数,必须在其中一个子动画中指定,而不是在Commit方法中指定。

Animation类还包括WithConcurrent可用于儿童动画添加到父方法Animation的对象。但是,它们的开始结束参数值不限于0到1,但只有对应于0到1范围的子动画的那部分将是活动的。例如,如果一个WithConcurrent方法调用定义了一个子动画靶向Scale1-6属性,但与开始结束的-2和3的值,则开始 -2值对应于Scale值1,并且结束的值3对应于Scale值6.由于0和1范围之外的值不会在动画中播放,因此该Scale属性将仅从3到6的动画。

取消动画

应用程序可以通过调用AbortAnimation扩展方法来取消动画,如下面的代码示例所示:

this.AbortAnimation ("SimpleAnimation");

请注意,动画所有者和动画名称的组合唯一标识动画。因此,必须指定运行动画时指定的所有者和名称才能取消动画。因此,代码示例将立即取消SimpleAnimation页面所拥有的动画。

创建自定义动画

到目前为止,这里显示的示例已经展示了可以通过ViewExtensions类中的方法同样实现的动画。但是,Animation该类的优点是它可以访问回调方法,该方法在动画值更改时执行。这允许回调来实现任何所需的动画。例如,以下代码示例BackgroundColor通过将页面的属性设置为Color通过Color.FromHsla方法创建的值来动画化属性,其中色调值的范围为0到1:

new Animation (callback: v => BackgroundColor = Color.FromHsla (v, 1, 0.5),
  start: 0,
  end: 1).Commit (this, "Animation", 16, 4000, Easing.Linear, (v, c) => BackgroundColor = Color.Default);

所产生的动画提供通过彩虹的颜色推进页面背景的外观。

为了创建复杂的动画,包括贝塞尔曲线动画的更多示例,请参见第22章与Xamarin.Forms创建移动应用程序

创建自定义动画扩展方法

类中的扩展方法ViewExtensions将属性从其当前值转换为指定值。这使得很难创建例如ColorTo可以用于将颜色从一个值赋给另一个值的动画方法,因为:

解决这个问题的ColorTo方法是没有一个特定的Color属性的方法。相反,它可以使用将内插值传递Color给调用者的回调方法来编写。此外,该方法将采用开始和结束Color参数。

ColorTo方法可以实现为使用类中的Animate方法AnimationExtensions来提供其功能的扩展方法。这是因为该Animate方法可用于定位不是类型的属性double,如以下代码示例所示:

public static class ViewExtensions
{
  public static Task<bool> ColorTo(this VisualElement self, Color fromColor, Color toColor, Action<Color> callback, uint length = 250, Easing easing = null)
  {
    Func<double, Color> transform = (t) =>
      Color.FromRgba(fromColor.R + t * (toColor.R - fromColor.R),
                     fromColor.G + t * (toColor.G - fromColor.G),
                     fromColor.B + t * (toColor.B - fromColor.B),
                     fromColor.A + t * (toColor.A - fromColor.A));
    return ColorAnimation(self, "ColorTo", transform, callback, length, easing);
  }

  public static void CancelAnimation(this VisualElement self)
  {
    self.AbortAnimation("ColorTo");
  }

  static Task<bool> ColorAnimation(VisualElement element, string name, Func<double, Color> transform, Action<Color> callback, uint length, Easing easing)
  {
    easing = easing ?? Easing.Linear;
    var taskCompletionSource = new TaskCompletionSource<bool>();

    element.Animate<Color>(name, transform, callback, 16, length, easing, (v, c) => taskCompletionSource.SetResult(c));
    return taskCompletionSource.Task;
  }
}

Animate方法需要一个转换参数,这是一个回调方法。此回调的输入始终double为0到1.因此,该ColorTo方法定义其自身的变换Func,接受double范围从0到1,并返回与该Color值对应的值。所述Color值通过内插所计算的RGB,和A的两个提供的值Color的参数。Color然后将该值传递给回调方法以应用于特定属性。

这种方法允许ColorTo方法为任何Color属性生成动画,如下面的代码示例所示:

await Task.WhenAll(
  label.ColorTo(Color.Red, Color.Blue, c => label.TextColor = c, 5000),
  label.ColorTo(Color.Blue, Color.Red, c => label.BackgroundColor = c, 5000));
await this.ColorTo(Color.FromRgb(0, 0, 0), Color.FromRgb(255, 255, 255), c => BackgroundColor = c, 5000);
await boxView.ColorTo(Color.Blue, Color.Red, c => boxView.Color = c, 4000);

在该代码示例中,ColorTo方法的动画TextColorBackgroundColor的性质Label的,BackgroundColor一个页面的属性和Color的特性BoxView

概要

本文演示了如何使用Animation类来创建和取消动画,同步多个动画,并创建自定义动画,使动画的属性不被现有的动画方法动画化。该Animation课程是所有Xamarin.Forms动画的构建块。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值