[译]: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来创建动画。
译:奇葩史