[译]:Xamarin.Android应用基础——图形和动画

标签: Xamarin.Android, 官方教程, 中文翻译

博客分类: 官方教程

返回索引目录
原文链接:Graphics and Animation
译文链接:Xamarin.Android应用基础——图形和动画

图形和动画

本文内容为关于Xamarin.Android中的图形和动画简介

Android中提供了一个非常丰富和多样化的框架来支持2D图形和动画。本文将介绍这些框架,并讨论如何在Xamarin.Android应用中创建及使用自定义图形和动画。

概览

辅助功能

2D图形

可绘制资源

可绘制资源使用示例

利用Canvas API

使用Canvas API绘图

动画

用户喜欢在应用中移动的东西。动画是改善一个应用用户体验及辅助突出它的一个好方法。最好的动画是 那些用户不会注意到的 —— 因为他们 会觉得很自然。Android提供了以下三个API来支持动画:

  • 视图动画-View Animation —— 这是最原始的API。这些动画会绑定到 特定的视图,并且可以对视图内容进行简单的转换。由于它比较简单,所以这个API依旧很有效,如透明度渐变动画、旋转等等。
  • 属性动画-Property Animation —— 属性动画是在Android 3.0中引入的。他们使得应用可以让几乎任何东西具有动画效果。属性动画可以用于改变任何对象的任何属性,包括那些在屏幕上不显示的对象。
  • 绘制动画-Drawable Animation —— 这是利用一个特殊的drawable资源来给布局添加一个非常简单的动画效果。

一般来说,属性动画是首选的系统,因为它更灵活,并且提供更多的功能。

视图动画

视图动画仅限于视图,且只能针对值执行动画(如起终点、大小、旋转和透明度)。这些类型动画通常叫做补间动画。视图动画 可以有两种方式来定义:代码编程方式 和XML文件声明方式。XML文件声明方式是视图动画的首选方式,因为它们更易于阅读与维护。

XML文件动画定义将存储在Xamarin.Android项目的/Resources/anim目录中。此文件中必须用以下几个元素中的一个作为根元素:

  • alpha —— 淡入淡出动画。
  • rotate —— 旋转动画。
  • scale —— 大小调整动画
  • translate —— 水平和/或垂直移动
  • set —— 一个或多个动画元素组合容器

默认情况下,XML文件中的所有动画都将同时应用。要使动画按照一定的顺序发送,则需要在 上面例举的几个元素中设置android:startOffset属性。

我们可以通过使用一个内插器(interpolator)来影响动画的变化速度。内插器可以用于加速动画、重复动画或者减速动画。Android框架中提供了几个内置的内插器,例如:—— 只例举部分

  • AccelerateInterpolator / DecelerateInterpolator —— 此类内插器用于动画的加速或减速
  • BounceInterpolator —— 变化在结束时反弹
  • LinearInterpolator —— 变化速度恒定

下面的XML内容展示了一个组合多个动画的动画文件的示例:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">

    <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromXScale="1.0"
        android:toXScale="1.4"
        android:fromYScale="1.0"
        android:toYScale="0.6"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fillEnabled="true"
        android:fillAfter="false"
        android:duration="700" />

    <set android:interpolator="@android:anim/accelerate_interpolator">
        <scale android:fromXScale="1.4"
            android:toXScale="0.0"
            android:fromYScale="0.6"
            android:toYScale="0.0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:fillEnabled="true"
            android:fillBefore="false"
            android:fillAfter="true"
            android:startOffset="700"
            android:duration="400" />

        <rotate android:fromDegrees="0"
                android:toDegrees="-45"
                android:toYScale="0.0"
                android:pivotX="50%"
                android:pivotY="50%"
                android:fillEnabled="true"
                android:fillBefore="false"
                android:fillAfter="true"
                android:startOffset="700"
                android:duration="400" />
    </set>
</set>

此动画将同时执行所有动画内容。其中第一个scale动画将水平拉伸图片并垂直压缩图片,然后图像将同时 逆时针旋转45度角并缩小、最后从屏幕中消失。

动画可以使用编程方式应用到视图(先为动画填充具体内容,然后将其应用到视图)。Android提供了一个辅助类Android.Views.Animations.AnimationUtils 来将填充动画资源,并返回一个Android.Views.Animations.Animation实例。此对象可以通过调用StartAnimation并传递Animation对象来应用到视图。以下代码段展示了一个示例:

Animation myAnimation = AnimationUtils.LoadAnimation(this,Resource.Animation.MyAnimation);
ImageView myImage = FindViewById<ImageView>(Resource.Id.imageView1);
myImage.StartAnimation(myAnimation);

现在我们已经基本了解了视图动画是如何工作的,下面看看属性动画内容。

属性动画

属性动画是在Android 3.0中引入的新的API。它们提供了一种更具扩展性的API —— 在任何对象的任何属性上设置动画。

所有的属性动画都是通过Animator的子类的实例来创建的。应用不会直接 使用Animator类,而是使用其的子类:

  • ValueAnimator —— 这个类是整个属性动画API中的最重要的类。它会计算要更改的属性值。但ViewAnimator不会直接更新这些值,而是通过触发更新动画对象的事件。
  • ObjectAnimator —— 此类是ValueAnimator的一个子类。它是通过接受待更新的目标对象和属性来简化对象的动画处理。
  • AnimationSet —— 此类是负责安排动画相互之间如何执行。动画可以同时执行,顺序执行,或者按照它们之间指定的延迟规则 运行。

Evaluators是一个特殊的类,动画制作者用它来计算一个动画中的新值。Android提供了以下几个内置的计算器(evaluator):

  • IntEvaluator —— 计算整型属性值
  • FloatEvaluator —— 计算浮点型属性值
  • ArgbEvaluator —— 计算颜色属性值

如果要设置动画的属性不是float、int或color,应用就需要通过实现ITypeEvaluator接口来创建自己的计算器。(实现自定义计算器不在本文讨论 范围)

使用ValueAnimator

任何动画都有两个部分:计算动画的值,然后将这些值设置到某些对象的属性上。ValueAnimator将只计算 这些值,而不会直接操作对象。但在动画生命周期期间,会调用事件处理程序,并在事件处理中更新对象。这个设计允许用一个动画值来更新多个属性。

你可以通过以下几个工厂方法来获取ValueAnimator的实例:

  • ValueAnimator.OfInt
  • ValueAnimator.OfFloat
  • ValueAnimator.OfObject

在获取到ValueAnimator实例后,你需要为其设置持续时间,然后才可以启动它。下面示例展示了如何在1000毫秒中让值从0到1的动画设置:

ValueAnimator animator = ValueAnimator.OfInt(0, 100);
animator.SetDuration(1000);
animator.Start();

但是,上面的代码本身并不是很有用 —— 动画将会运行,但是它没有更新目标。当Animator类需要通知侦听器有新值时,它会触发Update事件。应用可以通过提供事件处理程序来响应此事件,其代码如下:

MyCustomObject myObj = new MyCustomObject();
myObj.SomeIntegerValue = -1;

animator.Update += (object sender, ValueAnimator.AnimatorUpdateEventArgs e) =>
{
    int newValue = (int) e.Animation.AnimatedValue;
    // Apply this new value to the object being animated.
    myObj.SomeIntegerValue = newValue;
};

现在我们已经基本了解了ValueAnimator,下面会介绍ObjectAnimator。

使用ObjectAnimator

ObjectAnimator是ViewAnimator的一个子类,它将ValueAnimator的 定时引擎和值计算过程 与连接事件处理程序所需要的逻辑 进行组合 。ValueAnimator需要应用显示的注册一个事件处理程序 —— 而ObjectAnimator会帮助我们实现这一步。

ObjectAnimator的API与ViewAnimator的API非常相似,但是它需要你提供待更新的对象和对应的属性名。下面示例展示了如何使用ObjectAnimator:

原文ObjectAnimator.OfFloat有误,此处使用的属性类型应于其匹配。

MyCustomObject myObj = new MyCustomObject();
myObj.SomeIntegerValue = -1;

ObjectAnimator animator = ObjectAnimator.OfInt(myObj, "SomeIntegerValue", 0, 100);
animator.SetDuration(1000);
animator.Start();

从上面的代码片段可以看出,ObjectAnimator可以减少并简化设置对象动画的代码。

可绘制资源动画

最后一个要介绍的动画API是可绘制资源动画(Drawable Animation)API。可绘制资源动画会逐个加载一系列的Drawable资源,并按顺序展示它们(类似于翻转的卡通)。

Drawable资源是定义在一个XML文件中的。此 文件含有<animation-list>元素作为根元素,以及一系列用于定义每一帧动画的<item>元素。此XML文件存储在应用的/Resource/drawable文件夹中。下面为一个drawable动画的xml内容示例:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/asteroid01" android:duration="100" />
    <item android:drawable="@drawable/asteroid02" android:duration="100" />
    <item android:drawable="@drawable/asteroid03" android:duration="100" />
    <item android:drawable="@drawable/asteroid04" android:duration="100" />
    <item android:drawable="@drawable/asteroid05" android:duration="100" />
    <item android:drawable="@drawable/asteroid06" android:duration="100" />
</animation-list>

此动画含有6帧。android:duration属性说明了每一帧内容显示多长时间。下面的代码片段示例展示了怎样创建一个Drawable动画,并在用户点击屏幕上的按钮时启动动画:

AnimationDrawable _asteroidDrawable;

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.Main);

    _asteroidDrawable = (Android.Graphics.Drawables.AnimationDrawable)
    Resources.GetDrawable(Resource.Drawable.spinning_asteroid);

    ImageView asteroidImage = FindViewById<ImageView>(Resource.Id.imageView2);
    asteroidImage.SetImageDrawable((Android.Graphics.Drawables.Drawable) _asteroidDrawable);

    Button asteroidButton = FindViewById<Button>(Resource.Id.spinAsteroid);
    asteroidButton.Click += (sender, e) =>
    {
        _asteroidDrawable.Start();
    };
}

至此,我们已经知道了Android应用中可用动画API的基础。

总结

本篇文章介绍了许多新的概念和API,以此帮助我们向Android应用中添加一些图形。首先是讨论了各种2D图像API,并演示了Android是如何让应用利用Canvas对象直接在屏幕上绘制内容。同时,我们还介绍了一些替代技术 —— 利用声明式的方式在XML文件创建图形。然后,我们继续讨论了如何Android中使用新旧API来创建动画。


译:奇葩史

没有评论