分类:C#、Android、VS2015;

创建日期:2016-03-21

一、简介

Android 提供了以下三种创建动画的方式:

  • Drawable Animations – 画板动画,也叫帧动画(Frame Animations)。
  • View Animations - 视图动画,也叫补间动画(Tween Animations)。
  • Property Animations – 属性动画。从Android 3.0开始提供。

注意:虽然这三种动画都可用,但只要有可能,都应该优先考虑用属性动画来实现。另外,动画虽然能吸引人,但不要滥用,否则只会适得其反。

1、画板动画(Drawable Animations)

Drawable Animations提供了按帧播放的简单动画API,在其他实现技术中一般将其称为帧动画(Frame Animations)。这种动画的播放效果非常类似电影或卡通(cartoon)漫画。

帧动画是通过顺序播放图片来产生动画效果的,下图通过顺序播放6张图片实现一个人跳起来的动画效果:

控制动画序列的画板资源(XML文件)通常保存在应用程序的/Resource/drawable文件夹中,文件中用<animation-list>元素作为根元素,用<item>元素定义每一帧。

例如,在/Resource/drawable/ch2103DrawableAnimDemo.xml文件中定义动画序列:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/a01" android:duration="100" />

<item android:drawable="@drawable/a02" android:duration="100" />

<item android:drawable="@drawable/a03" android:duration="100" />

<item android:drawable="@drawable/a04" android:duration="100" />

<item android:drawable="@drawable/a05" android:duration="100" />

<item android:drawable="@drawable/a06" android:duration="100" />

</animation-list>

此动画包含六个帧。其中,a01~a06是图片文件,android:duration属性声明每个帧显示的时间。定义动画序列以后,只需要在布局文件中指定该文件,Android就会自动按顺序加载和显示动画。

2、视图动画(View Animations)

在Android系统中,视图动画(或者叫补间动画)有4种表现方式:渐变、缩放、平移、旋转。利用View动画能完成一系列诸如位置、大小、不透明度、旋转等简单的变化。例如对程序中的某个ImageView实现动画处理等。

View动画位于Android.View.Animation命名空间中,在代码中可通过下面的方法对View对象进行动画处理:

AlphaAnimation:控制不透明度变化的动画类

Rotate Animation:控制旋转的动画类

ScaleAnimation:控制缩放变化的动画类

TranslateAnimation:控制平移变化的动画类

AnimationSet:控制动画属性的集合类

动画变换文件一般保存在/Resources/anim文件夹中。另外,虽然此API是早期版本提供的,但是由于它的简单性,因此仍然有用。

注意:保存在/Resources/anim文件夹中的XML文件是声明View动画的首选办法,因为这种方式更易于阅读和维护。该XML文件必须用以下元素之一作为根元素:

  • alpha -淡入或淡出动画
  • rotate -旋转动画
  • scale –缩放动画
  • translate –平移(水平或垂直运动)
  • set - 动画容器,可容纳一个或多个其他动画元素

默认情况下,Android会同时应用该XML文件中的所有动画。要使动画按指定的顺序变化,将android:startOffset属性设置在上面定义的元素之一即可。

也可以内插器改变动画速率,如加速、重复、减速等动画效果:

  • AcclerateInterpolator / DecelerateInterpolator –增加或减少动画速率
  • BounceInterpolator – 动画结束时反弹
  • LinearInterpolator – 恒定速率

具体用法见本节示例中的“视图动画示例”。在这个例子中,动画效果是先将图像沿水平和垂直方向缩放,然后将图像逆时针旋转45度同时缩小图像的大小。

3、属性动画(Property Animations)

这种动画可对任何对象的属性进行处理(包括View),是首选的执行动画的方式,即使动画对象不可见也一样能对其进行处理。

属性动画API的灵活性在于还能将动画封装在不同的类中,使代码共享更加方便。

所有属性动画都是通过Animator子类的实例来创建:

  • ValueAnimator – 这是整个属性动画API中最重要的类。它会自动计算需要更改的属性值,该动画并不是直接修改这些值,而是用事件去更新动画对象。
  • ObjectAnimator – 对目标对象的某个属性进行动画处理。
  • AnimationSet – 此类用于保存动画集合,程序中利用它可以“同时执行、顺序执行、延时执行”这些动画。

使用动画是,可能还需要下面的特殊类:

  • IntEvaluator – 计算整数类型的属性值
  • FloatEvaluator –计算浮点类型的属性值
  • ArgbEvaluator –计算颜色类型的属性值

如果正在进行动画处理的属性不是float、int或Color,可通过实现ITypeEvaluator接口创建他们自己的计算类型。

(1)ValueAnimator

通过调用下面的方法之一,可获取得ValueAnimator的实例:

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

下面的代码演示如何将值从 0 到 100进行动画处理,动画持续时间为1000毫秒。

ValueAnimator animator = ValueAnimator.OfInt(0, 100);

animator.SetDuration(1000);

animator.Start();

但是,仅有这些代码还不够,这是因为虽然执行了动画但是并没有将目标更新为新的值,因此还需要引入相关的事件:

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;

};

(2)ObjectAnimator

ObjectAnimator是ViewAnimator的子类,它将计时引擎和ValueAnimator结合在一起实现动画。例如:

MyCustomObject myObj = new MyCustomObject();

myObj.SomeIntegerValue = -1;

ObjectAnimator animator = ObjectAnimator.OfFloat(myObj, "SomeIntegerValue”, 0, 100);

animator.SetDuration(1000);

animator.Start();

与前面的代码相比,这样做可减少代码量。

二、示例

1、运行截图

【Android】21.3 动画_第1张图片

2、设计步骤

(1)添加图片

在Drawable文件夹下添加6个图片(ch2103asteroid01.png~ch2103asteroid06.png),这些图片用于演示帧动画的用法。

然后再添加一个ch2103ship.png图片,该图片用于演示视图动画的用法。

(2)添加ch2103DrawableAnimDemo.xml

在Resources/Drawable文件夹下添加该文件。

<?xml version="1.0" encoding="UTF-8" ?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" >  <item android:drawable="@drawable/ch2103asteroid01" android:duration="100" />  <item android:drawable="@drawable/ch2103asteroid02" android:duration="100" />  <item android:drawable="@drawable/ch2103asteroid03" android:duration="100" />  <item android:drawable="@drawable/ch2103asteroid04" android:duration="100" />  <item android:drawable="@drawable/ch2103asteroid05" android:duration="100" />  <item android:drawable="@drawable/ch2103asteroid06" android:duration="100" /></animation-list>

(3)添加ch2103ViewAnimDemo.xml

在Resources/anim文件夹下添加该文件。

<?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>

(4)添加ch2103Main.axml

在Resources/layout文件夹下添加该文件。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:minWidth="25px"    android:minHeight="25px">    <TextView        android:text="画板动画示例"        android:textAppearance="?android:attr/textAppearanceSmall"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:background="@color/myGray"        android:layout_marginTop="5dp" />    <ImageView        android:src="@android:drawable/ic_menu_gallery"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/ch2103_imageView_DrawableDemo"        android:layout_marginTop="5dp" />    <TextView        android:text="视图动画示例"        android:textAppearance="?android:attr/textAppearanceSmall"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:background="@color/myGray"        android:layout_marginTop="5dp" />    <ImageView        android:src="@android:drawable/ic_menu_gallery"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/ch2103_imageView_ViewDemo"        android:layout_marginLeft="20dp"        android:layout_marginTop="5dp" />    <Button        android:text="开始"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/ch2103_btnViewDemoStart"        android:layout_gravity="center" />    <TextView        android:text="属性动画示例(拖放滑动条观察进度条动画)"        android:textAppearance="?android:attr/textAppearanceSmall"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:background="@color/myGray"        android:layout_marginTop="5dp" />    <FrameLayout        android:minWidth="25px"        android:minHeight="35px"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:id="@+id/frameLayout1"        android:layout_marginTop="15dp"        android:layout_marginBottom="5dp">        <MyDemos.SrcDemos.ch2103MyView            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_marginLeft="8dp"            android:layout_marginRight="8dp"            android:id="@+id/ch2103myview1" />    </FrameLayout>    <SeekBar        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:id="@+id/ch2103seekBar1"        android:max="100"        android:progress="50"        android:layout_marginLeft="8dp"        android:layout_marginRight="8dp"        android:layout_marginTop="10dp" /></LinearLayout>

(5)添加ch2103MyView.cs

using System;using Android.Content;using Android.Views;using Android.Graphics;using Android.Util;using Android.Animation;namespace MyDemos.SrcDemos{    /// <summary>    /// 演示进度条动画控制的基本用法    /// </summary>    public class ch2103MyView : View    {        private const int DefaultHeight = 20;        private const int DefaultWidth = 120;        private Paint mNegativePaint;        private double mPosition = 0.5;        private Paint mPositivePaint;        public ch2103MyView(Context context, IAttributeSet attrs)            : this(context, attrs, 0)        {            Initialize();        }        public ch2103MyView(Context context, IAttributeSet attrs, int defStyle)            : base(context, attrs, defStyle)        {            Initialize();        }        public double CurrentValue        {            get { return mPosition; }            set            {                mPosition = Math.Max(0f, Math.Min(value, 1f));                Invalidate();            }        }        public void SetCurentValue(double value, bool animate)        {            if (!animate)            {                CurrentValue = value;                return;            }            ValueAnimator animator = ValueAnimator.OfFloat((float)mPosition, (float)Math.Max(0f, Math.Min(value, 1f)));            animator.SetDuration(500);            animator.Update += (sender, e) => CurrentValue = (double)e.Animation.AnimatedValue;            animator.Start();        }        protected override void OnDraw(Canvas canvas)        {            base.OnDraw(canvas);            float middle = canvas.Width * (float)mPosition;            canvas.DrawPaint(mNegativePaint);            canvas.DrawRect(0, 0, middle, canvas.Height, mPositivePaint);        }        protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)        {            int width = MeasureSpec.GetSize(widthMeasureSpec);            SetMeasuredDimension(width < DefaultWidth ? DefaultWidth : width, DefaultHeight);        }        private void Initialize()        {            mPositivePaint = new Paint            {                AntiAlias = true,                Color = Color.Rgb(0x99, 0xcc, 0),            };            mPositivePaint.SetStyle(Paint.Style.FillAndStroke);            mNegativePaint = new Paint            {                AntiAlias = true,                Color = Color.Rgb(0xff, 0x44, 0x44)            };            mNegativePaint.SetStyle(Paint.Style.FillAndStroke);        }    }}

(6)添加ch2103MainActivity.cs

using Android.App;using Android.OS;using Android.Widget;using Android.Views.Animations;namespace MyDemos.SrcDemos{    [Activity(Label = "【例21-3】动画基本用法")]    public class ch2103MainActivity : Activity    {        protected override void OnCreate(Bundle savedInstanceState)        {            base.OnCreate(savedInstanceState);            SetContentView(Resource.Layout.ch2103Main);            //画板动画Demo            var img1 = FindViewById<ImageView>(Resource.Id.ch2103_imageView_DrawableDemo);            img1.SetImageResource(Resource.Drawable.ch2103DrawableAnimDemo);            //视图动画Demo            var btn1 = FindViewById<Button>(Resource.Id.ch2103_btnViewDemoStart);            btn1.Click += (sender, args) => {                Animation animation = AnimationUtils.LoadAnimation(this, Resource.Animation.ch2103ViewAnimDemo);                var img2 = FindViewById<ImageView>(Resource.Id.ch2103_imageView_ViewDemo);                img2.SetImageResource(Resource.Drawable.ch2103ship);                img2.StartAnimation(animation);            };            //属性动画Demo            var myView = FindViewById<ch2103MyView>(Resource.Id.ch2103myview1);            var seekBar = FindViewById<SeekBar>(Resource.Id.ch2103seekBar1);            seekBar.StopTrackingTouch += (sender, args) =>            {                double currentValue = ((double)seekBar.Progress) / seekBar.Max;                 myView.SetCurentValue(currentValue, true);            };        }    }}

更多相关文章

  1. [置顶] android:configChanges属性
  2. Android 文件读写操作 总结
  3. Android基础知识:Day02 常见布局、logcat相关和文件读写
  4. Android动画的使用
  5. ANDROID开机动画bootanimation.zip的详细制作方法
  6. android解析xml文件的方式

随机推荐

  1. Android(安卓)Intent的详细解析以及用法
  2. TextView 最多显示2行,每行最多8个字,多余
  3. Android手动显示和隐藏软键盘方法总结
  4. android的adb详解(多设备时adb调用)
  5. Android(安卓)Studio官方文档之Android(
  6. Android开发笔记 TableLayout常用的属性
  7. Android(安卓)WebView 开发详解(一)
  8. android 进程优先级
  9. Android高手应该精通哪些内容
  10. Android(安卓)System Server大纲之Conten