Android详细教程(基础篇):二十九、Android 多媒体技术之Paint 、Bitmap、 Matrix、 Animation详解

本文详细介绍了Android多媒体技术,包括Paint的使用,Bitmap的基础与操作,Matrix在图形变换中的作用,以及Animation的分类、定义与使用,如Tween Animation和Frame Animation。同时讲解了Animation的Interpolator、Transformation类以及AnimationSet、LayoutAnimationsController的运用,展示了如何在ListView中结合使用Animation。

多媒体技术

  1. Paint(绘图)

public class

Paint

extends Object

java.lang.Object

   

android.graphics.Paint

 

Known Direct Subclasses

TextPaint

 

 

使用Paint绘制图形

View:

package com.makyan.demo;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Paint.Style;

import android.graphics.Rect;

import android.graphics.RectF;

import android.util.AttributeSet;

import android.view.View;

public class MyView extends View {

            public MyView(Context context, AttributeSet attrs) {

                       super(context, attrs);

            }

            @Override

            protected void onDraw(Canvas canvas) {                                               // 覆写绘图方法

                       canvas.drawColor(Color.WHITE) ;                                                            // 设置背景颜色

                       Paint paint = new Paint() ;                                                                        // 定义Paint对象

                       paint.setColor(Color.BLUE) ;                                                                    // 设置为蓝色显示

                       canvas.drawCircle(30, 50, 25, paint) ;                                          // 画圆

                       paint.setColor(Color.BLACK) ;                                                                  // 设置为黑色显示

                       canvas.drawRect(80, 20, 160, 80, paint) ;                        // 画矩形

                       Rect rect = new Rect() ;                                                                            // 定义矩形

                       rect.set(180, 20, 300, 80);                                                                        // 设置矩形大小

                       paint.setStyle(Style.STROKE);                                                                   // 空心显示

                       canvas.drawRect(rect, paint) ;                                                                 // 画矩形

                       paint.setColor(Color.RED) ;                                                                      // 设置为红色

                       paint.setTextSize(20) ;                                                                                          // 设置字体大小

                       canvas.drawText("杨雄android工作室", 10, 110, paint);       // 显示文字

                       paint.setColor(Color.BLACK) ;                                                                  // 设置为黑色显示

                       canvas.drawLine(10, 120, 300, 120, paint);                                // 画线

                       RectF oval = new RectF() ;                                                                        // 定义参考矩形

                       oval.set(10.0f, 140.0f, 110.0f, 200.0f);                             // 定义大小

                       canvas.drawOval(oval, paint) ;                                                                 // 画椭圆

                       oval = new RectF() ;                                                                                  // 定义参考矩形

                       oval.set(150.0f, 140.0f, 210.0f, 200.0f);                          // 定义大小

                       canvas.drawArc(oval, 150.0f, 140.0f, true, paint) ;// 画弧

            }

}

 

组件配置(配置自己的视图):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".PaintActivity" >

    <com.makyan.demo.MyView

        android:id="@+id/myView"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"/>

</LinearLayout>

 

  1. Bitmap(位图)
    1. Bitmap简介

public final class

Bitmap

extends Object

implements Parcelable

java.lang.Object

   

android.graphics.Bitmap

 

 

Bitmap是Android手机中专门提供的用于操作图片资源的操作类,使用此类可以直接从资源文件之中进行图片

资源的读取,并且对这些图片进行一些简单的修改。

 

范例:使用Bitmap进行绘图

View:

package com.makyan.demo;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.AttributeSet;

import android.view.View;

public class MyView extends View {

            public MyView(Context context, AttributeSet attrs) {

                       super(context, attrs);

            }

            @Override

            protected void onDraw(Canvas canvas) {                                   // 绘图

                       Bitmap bitmap = BitmapFactory.decodeResource(super.getResources(),

                                               R.drawable.tt);

                       Paint paint = new Paint();

                       paint.setAntiAlias(true);                                                               // 消除锯齿

                       canvas.drawBitmap(bitmap, 0, 0, paint);            // 画图

                       paint.setColor(Color.BLUE);                                                         // 蓝色字体

                       paint.setTextSize(20);                                                                               // 定义字号

                       canvas.drawText(

                                               "图片高度:" + bitmap.getHeight() + ",图片宽度:" + bitmap.getWidth(),

                                               10, bitmap.getHeight() + 20, paint);         // 输出文字

            }

}

 

组件配置:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".BitmapActivity" >

    <com.makyan.demo.MyView

        android:id="@+id/myview"

                       android:layout_width="fill_parent"

                       android:layout_height="fill_parent" />

</LinearLayout>

范例:使用DisplayMetrics将图片的宽和高设置为屏幕的宽和高

修改View:

package com.makyan.demo;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.view.View;

public class MyView extends View {

            public MyView(Context context, AttributeSet attrs) {

                       super(context, attrs);

            }

            @Override

            protected void onDraw(Canvas canvas) {                                   // 绘图

                       DisplayMetrics dm = getResources().getDisplayMetrics();

                       int screenWidth = dm.widthPixels ;                                             // 取得手机屏幕的宽度

                       int screenHeight = dm.heightPixels ;                               // 取得手机屏幕的高度

                       Bitmap bitmap = BitmapFactory.decodeResource(super.getResources(),

                                               R.drawable.tt);                                            // 取得Bitmap

                       bitmap = Bitmap.createScaledBitmap(bitmap, screenWidth, screenHeight,

                                               true);                                                                                              // 创建一个指定大小的图片

                       Paint paint = new Paint();

                       paint.setAntiAlias(true);                                                               // 消除锯齿

                       canvas.drawBitmap(bitmap, 0, 0, paint);            // 画图

            }

}

 

范例:将图片在指定位置显示:

修改View:

package com.makyan.demo;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.Rect;

import android.util.AttributeSet;

import android.view.View;

public class MyView extends View {

            public MyView(Context context, AttributeSet attrs) {

                       super(context, attrs);

            }

            @Override

            protected void onDraw(Canvas canvas) {                                   // 绘图

                       Bitmap bitmap = BitmapFactory.decodeResource(super.getResources(),

                                               R.drawable.tt);                                            // 取得Bitmap

                       Paint paint = new Paint();

                       paint.setAntiAlias(true);                                                               // 消除锯齿

                       canvas.drawBitmap(bitmap, null, new Rect(30, 50, 200, 200),

                                               paint);                                                                                            // 画图

            }

}

 

范例:剪切图片:

修改View:

package com.makyan.demo;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.Rect;

import android.util.AttributeSet;

import android.view.View;

public class MyView extends View {

            public MyView(Context context, AttributeSet attrs) {

                       super(context, attrs);

            }

            @Override

            protected void onDraw(Canvas canvas) {                                   // 绘图

                       Bitmap bitmap = BitmapFactory.decodeResource(super.getResources(),

                                               R.drawable.tt);                                            // 取得Bitmap

                       Paint paint = new Paint();

                       paint.setAntiAlias(true);                                                               // 消除锯齿

                       canvas.drawBitmap(bitmap, new Rect(10,10,100,100), new Rect(10,10,100,100),

                                               paint);                                                                                            // 画图

            }

}

 

  1. Matrix(矩阵)
    1. Matrix简介

public class

Matrix

extends Object

java.lang.Object

   

android.graphics.Matrix

 

 

使用Bitmap可以进行图形的绘制,但是如果希望图形可以进行一些平移、旋转、缩放、倾斜等变换的话,则需要

Matrix类的支持。

Matrix类操作流程:

 

范例:为60度时的矩阵

View:

package com.makyan.demo;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Matrix;

import android.util.AttributeSet;

import android.view.View;

public class MyView extends View {

            private Bitmap bitmap = null ;

            private Matrix matrix = new Matrix();

            public MyView(Context context, AttributeSet attrs) {

                       super(context, attrs);

                       this.bitmap = BitmapFactory.decodeResource(super.getResources(),

                                               R.drawable.dg);                                                      // 取得Bitmap

                       float cosValue = (float) Math.cos(-Math.PI/3);               // 60

                       float sinValue = (float) Math.sin(-Math.PI/3);    // 60

                       this.matrix.setValues(new float[] {

                                               cosValue,      // X轴的缩放,1表示原始大小

                                               -sinValue,      // 旋转的X

                                               100,               // x轴平移

                                               sinValue,       // 旋转Y

                                               cosValue,      // Y轴的缩放,1表示原始大小

                                               200,               // y轴平移

                                               0, 0,                // 视角转换

                                               2 });                // 缩放比例,1不变,2表示1/2

            }

            @Override

            protected void onDraw(Canvas canvas) {                                               // 绘图

                       canvas.drawBitmap(this.bitmap, this.matrix, null); // 画图

            }

}

 

组件配置:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MatrixActivity" >

    <com.makyan.demo.MyView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"/>

</RelativeLayout>

以上是使用矩阵的公式设置图片的

也可以使用Matrix提供的方法直接设置图片的位置

View:

package com.makyan.demo;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Matrix;

import android.util.AttributeSet;

import android.view.View;

public class MyView extends View {

            private Bitmap bitmap = null ;

            private Matrix matrix = new Matrix();

            public MyView(Context context, AttributeSet attrs) {

                       super(context, attrs);

                       this.bitmap = BitmapFactory.decodeResource(super.getResources(),

                                               R.drawable.dg);                                                      // 取得Bitmap

                       this.matrix.preScale(0.5f, 0.5f, 50, 100);                         // 缩小一倍

                       this.matrix.preRotate(-60, 50, 100) ;                                // 在指定坐标翻转60

                       this.matrix.preTranslate(50, 100) ;                                    // 图象平移

            }

            @Override

            protected void onDraw(Canvas canvas) {                                               // 绘图

                       canvas.drawBitmap(this.bitmap, this.matrix, null); // 画图

            }

}

 

  1. Animation(动画)

4.1.Animation分类

Drawable 最强大的功能是:显示AnimationAndroidSDK介绍了2Animation

  • Tween Animation(渐变动画):通过对场景里的对象不断做图像变换(平移、缩放、旋转)产生动画效果
  • Frame Animation(帧动画)   :顺序播放事先做好的图像,类似放电影

4.2.Tween Animation

在使用Animation前,我们先学习如何定义Animation,这对我们使用Animation会有很大的帮助。Animation是以XML格式定义的,定义好的XML文件存放在res/anim中。 由于Tween AnimationFrame Animation的定义、使用都有很大的差异,我们将分开介绍,本篇幅中介绍Tween Animation的定义与使用,后续篇幅再详细介绍Frame Animation。按照XML文档的结构【父节点,子节点,属性】来介绍Tween Animation,其由4种类型:

  • Alpha:渐变透明度动画效果
  • Scale:渐变尺寸伸缩动画效果
  • Translate:画面转换位置移动动画效果
  • Rotate:画面转换位置移动动画效果

4.2.1. Tween Animation属性

在介绍以上4种类型前,先介绍Tween Animation共同的节点属性。

表一

属性[类型]

功能

 

Duration[long]

属性为动画持续时间

时间以毫秒为单位

fillAfter [boolean]

当设置为true ,该动画转化在动画结束后被应用

fillBefore[boolean]

当设置为true ,该动画转化在动画开始前被应用

interpolator

指定一个动画的插入器

有一些常见的插入器

accelerate_decelerate_interpolator

加速-减速 动画插入器

accelerate_interpolator

加速-动画插入器

decelerate_interpolator

减速- 动画插入器

其他的属于特定的动画效果

repeatCount[int]

动画的重复次数

 

repeatMode[String]

定义重复的行为

1"restart" 2"reverse"   eg: android:repeatMode="reverse"

startOffset[long]

动画之间的时间间隔,从上次动画停多少时间开始执行下个动画

zAdjustment[int]

定义动画的Z Order的改变

0:保持Z Order不变

1:保持在最上层

-1:保持在最下层

看了以上节点,大家是不是都想开始定义动画了。下面我们就开始结合具体的例子,

介绍4种类型各自特有的节点元素。

表二

XML节点

功能说明

alpha

渐变透明度动画效果

<alpha

android:fromAlpha=”0.1″

android:toAlpha=”1.0″

android:duration=”3000″ />

fromAlpha

属性为动画起始时透明度

0.0表示完全透明

1.0表示完全不透明

以上值取0.0-1.0之间的float数据类型的数字

toAlpha

属性为动画结束时透明度

 

表三

scale

渐变尺寸伸缩动画效果

<scale

android:interpolator= “@android:anim/accelerate_decelerate_interpolator”

android:fromXScale=”0.0″

android:toXScale=”1.4″

android:fromYScale=”0.0″

android:toYScale=”1.4″

android:pivotX=”50%”

android:pivotY=”50%”

android:fillAfter=”false”

android:startOffset=“700”

android:duration=”700″

android:repeatCount=”10″ />

fromXScale[float] fromYScale[float]

为动画起始时,XY坐标上的伸缩尺寸

0.0表示收缩到没有

1.0表示正常无伸缩

值小于1.0表示收缩

值大于1.0表示放大

toXScale [float]

toYScale[float]

为动画结束时,XY坐标上的伸缩尺寸

pivotX[float]

pivotY[float]

为动画相对于物件的XY坐标的开始位置

属性值说明:从0%-100%中取值,50%为物件的XY方向坐标上的中点位置

 

 

 

 

 

表四

translate

画面转换位置移动动画效果

<translate

android:fromXDelta=”30″

android:toXDelta=”-80″

android:fromYDelta=”30″

android:toYDelta=”300″

android:duration=”2000″ />

fromXDelta

toXDelta

为动画、结束起始时 X坐标上的位置

 

fromYDelta

toYDelta

为动画、结束起始时 Y坐标上的位置

 

 

 

 

 

 

表五

rotate

画面转移旋转动画效果

<rotate

android:interpolator=”@android:anim/accelerate_decelerate_interpolator”

android:fromDegrees=”0″

android:toDegrees=”+350″

android:pivotX=”50%”

android:pivotY=”50%”

android:duration=”3000″ />

fromDegrees

为动画起始时物件的角度

说明

当角度为负数——表示逆时针旋转

当角度为正数——表示顺时针旋转

(负数from——to正数:顺时针旋转)

(负数from——to负数:逆时针旋转)

(正数from——to正数:顺时针旋转)

(正数from——to负数:逆时针旋转)

toDegrees

属性为动画结束时物件旋转的角度 可以大于360

pivotX

pivotY

为动画相对于物件的XY坐标的开始位

说明:以上两个属性值 0%-100%中取值

50%为物件的XY方向坐标上的中点位置

 

 

 

 

4.2.2. 操作Tween Animation的相关类

按照上面的讲述学习完了Tween Animation的定义,对Tween Animation有了详细的了解,再去了解下Android SDK

animation packageandroid.view.animation),其提供了操作Tween Animation所有的类。

Android SDK提供了基类:Animation,包含大量的set/getXXXX()函数来设置、读取Animation的属性,也就是前面表一中显示的各种属性。

Tween Animation4种类型:alphascaletranslateroate,在Android SDK中提供了相应的类,Animation类派生出了AlphaAnimationScaleAnimation

TranslateAnimationRotateAnimation分别实现了平移、旋转、改变 Alpha 值等动画,每个子类都在父类的基础上增加了各自独有的属性。

再去看下这几个类的构造函数,是不是与我们在表二、表三、表四、表五种定义的属性完全一样。

4.2.3. Tween Animation的使用

在了解了Tween Animation的定义,对android.view.animation有了一些基本的认识后,开始介绍Tween Animation如何使用。Android SDK提供了2种方法:

1、直接从XML资源中读取Animation

2、使用Animation子类的构造函数来初始化Animation对象

第二种方法在看了Android SDK中各个类的说明就知道如何使用了,下面简要说明从XML资源中读取Animation,按照应用程序开发的过程,介绍整个使用的过程,如下:

1、创建Android工程;

2、导入一张图片资源;

3、在res/layout/main.xml中添加一个 ImageView Widget;

4、在res下创建新的文件夹且命名为:anim,并在此文件夹下面定义 Animation XML 文件;

5、修改OnCreate()中的代码,显示动画资源;

关键代码,解析如下:

//main.xml中的ImageView

ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);

//加载动画

Animation hyperspaceJumpAnimation =

AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);

//使用ImageView显示动画

spaceshipImage.startAnimation(hyperspaceJumpAnimation);

这里简要解析如下:

  • AnimationUtils提供了加载动画的函数,除了函数loadAnimation(),其他的到Android SDK中去详细了解吧;
  • 所谓的动画,也就是对 view 的内容做一次图形变换;

4.2.4. Animation 应用

Tween Animation的本质做个总结:Tween Animation通过对 View 的内容完成一系列的图形变换 (包括平移、缩放、旋转、

改变透明度)来实现动画效果。具体来讲,预先定义一组指令,这些指令指定了图形变换的类型、触发时间、持续时间。这些指令

可以是 XML 文件方式定义,也可以是以源代码方式定义。程序沿着时间线执行这些指令就可以实现动画效果。

在这里,我们需要对2个问题进行深入的解析:

  • 动画运行时如何控制?
  • 动画的运行模式。

4.2.4.1. 如何控制动画的运行?

这个问题,我们也就也就是上一篇幅中提到的Tween Animation,估计大家对什么是Interpolator、到底有什么作用,还是一头雾水,在这里做个详细的说明。按照Android SDK中对interpolator的说明:interpolator定义一个动画的变化率(the rate of change)。这使得基本的动画效果(alpha, scale, translate, rotate)得以加速,减速,重复等。

用通俗的一点的话理解就是:动画的进度使用 Interpolator 控制。Interpolator 定义了动画的变化速度,可以实现匀速、正加速、负加速、无规则变加速等。Interpolator 是基类,封装了所有 Interpolator 的共同方法,它只有一个方法,即 getInterpolation (float input),该方法 maps a point on the timeline to a multiplier to be applied to the transformations of an animationAndroid 提供了几个 Interpolator 子类,实现了不同的速度曲线,如下

 

Interpolator对象

资源ID

功能作用

AccelerateDecelerateInterpolator

@android:anim/accelerate_decelerate_interpolator

先加速再减速

AccelerateInterpolator

@android:anim/accelerate_interpolator

加速

AnticipateInterpolator

@android:anim/anticipate_interpolator

先回退一小步然后加速前进

AnticipateOvershootInterpolator

@android:anim/anticipate_overshoot_interpolator

在上一个基础上超出终点一小步再回到终点

BounceInterpolator

@android:anim/bounce_interpolator

最后阶段弹球效果

CycleInterpolator

@android:anim/cycle_interpolator

周期运动

DecelerateInterpolator

@android:anim/decelerate_interpolator

减速

LinearInterpolator

@android:anim/linear_interpolator

匀速

OvershootInterpolator

@android:anim/overshoot_interpolator

快速到达终点并超出一小步最后回到终点

 

对于 LinearInterpolator ,变化率是个常数,即 f (x) = x.

public float getInterpolation(float input) {

 

 return input;

}

Interpolator其他的几个子类,也都是按照特定的算法,实现了对变化率。还可以定义自己的 Interpolator 子类,实现抛物线、自由落体等物理效果。

4.2.4.2. 动画的运行模式

动画的运行模式有两种:

  • 独占模式,即程序主线程进入一个循环,根据动画指令不断刷新屏幕,直到动画结束;
  • 中断模式,即有单独一个线程对时间计数,每隔一定的时间向主线程发通知,主线程接到通知后更新屏幕;

4.2.5. Transformation 类

Transformation 记录了仿射矩阵 Matrix,动画每触发一次,会对原来的矩阵做一次运算, View 的 Bitmap 与这个矩阵相乘就可实现相应的操作(旋转、平移、缩放等)。Transformation 类封装了矩阵和 alpha 值,它有两个重要的成员,一是 mMatrix,二是 mAlpha。Transformation 类图如下所示:

 

总结说明

图形变换通过仿射矩阵实现。图形变换是图形学中的基本知识,简单来讲,每种变换都是一次矩阵运算。在 Android 中,Canvas 类中包含当前矩阵,当调用 Canvas.drawBitmap (bmp, x, y, Paint) 绘制时,Android 会先把 bmp 做一次矩阵运算,然后将运算的结果显示在 Canvas 上。这样,编程人员只需不断修改 Canvas 的矩阵并刷新屏幕,View 里的对象就会不停的做图形变换,因此就形成了动画。

4.3.Frame Animation

前面我们详细介绍了Tween  Aniamation,这节我将介绍另外一种动画Frame Animation。在前面已经说过,Frame Animation是顺序播放事先做好的图像,与电影类似。不同于animation package Android SDK提供了另外一个类AnimationDrawable来定义、使用Frame Animation

Frame Animation可以在XML Resource定义(还是存放到res/anim文件夹下),也可以使用AnimationDrawable中的API定义。 由于Tween AnimationFrame Animation有着很大的不同,因此XML定义的格式也完全不一样,其格式是:首先是animation-list根节点,animation- list根节点中包含多个item子节点,每个item节点定义一帧动画:当前帧的drawable资源和当前帧持续的时间。下面对节点的元素加以说明:

XML属性

说明

drawable

当前帧引用的drawable资源

duration

当前帧显示的时间(毫秒为单位)

oneshot

如果为true,表示动画只播放一次停止在最后一帧上,如果设置为false表示动画循环播放。

variablePadding

If true, allows the drawable’s padding to change based on the current state that is selected.

visible

规定drawable的初始可见性,默认为flase

下面就给个具体的XML例子,来定义一帧一帧的动画:

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

android:oneshot=”true”>

   <item android:drawable=”@drawable/rocket_thrust1″ android:duration=”200″ />

   <item android:drawable=”@drawable/rocket_thrust2″ android:duration=”200″ />

   <item android:drawable=”@drawable/rocket_thrust3″ android:duration=”200″ />

</animation-list>

上面的XML就定义了一个Frame Animation,其包含3帧动画,3帧动画中分别应用了drawable中的3张图片:rocket_thrust1rocket_thrust2rocket_thrust3,每帧动画持续200毫秒。

然后我们将以上XML保存在res/anim/文件夹下,命名为rocket_thrust.xml,显示动画的代码,如下:在OnCreate()中增加如下代码:

ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);

rocketImage.setBackgroundResource(R.anim.rocket_thrust);

rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

最后还需要增加启动动画的代码:

public boolean onTouchEvent(MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN) {

rocketAnimation.start();

return true;

 }

 return super.onTouchEvent(event);

}

代码运行的结果想必大家应该就知道了(3张图片按照顺序的播放一次),不过有一点需要强调的是:启动Frame Animation动画的代码rocketAnimation.start(); 不能在OnCreate()中,因为在OnCreate()中AnimationDrawable还没有完全的与ImageView绑定,在OnCreate()中启动动画,就只能看到第一张图片。

下面,阅读Android SDK中对AnimationDrawable的介绍,有个简单的了解:

AnimationDrawable

获取、设置动画的属性

 

int getDuration()

获取动画的时长

int getNumberOfFrames()

获取动画的帧数

boolean isOneShot()

 

 

Void setOneShot(boolean oneshot)

获取oneshot属性

设置oneshot属性

void inflate(Resurce r,XmlPullParser p,

AttributeSet attrs)

 

增加、获取帧动画

Drawable getFrame(int index)

获取某帧的Drawable资源

void addFrame(Drawable frame,int duration)

为当前动画增加帧(资源,持续时长)

动画控制

void start()

开始动画

void run()

外界不能直接掉调用,使用start()替代

boolean  isRunning()

当前动画是否在运行

void stop()

停止当前动画

总结说明

Frame Animation的定义、使用比较简单,在这里已经详细介绍完了,更加深入的学习还是到Android SDK去仔细了解吧,在Android SDK中也包含很多这方面的例子程序。注:Frame Animation XML 文件中不定义 interpolator 属性,因为定义它没有任何意义。

4.4. AnimationSet的具体使用

1.AnimationSetAnimation的子类;

2.一个AnimationSet包含了一系列的Animation

3.针对AnimationSet设置一些Animation的常见属性(如startOffsetduration等),可以被包含在AnimationSet当中的Animation集成;

 

例:一个AnimationSet中有两个Animation,效果叠加

AnimationSet animationSet = new AnimationSet(true); 

AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0); 

RotateAnimation rotateAnimation = new RotateAnimation(0, 360

        Animation.RELATIVE_TO_SELF,0.5f

        Animation.RELATIVE_TO_SELF,0.5f); 

rotateAnimation.setDuration(1000); 

animationSet.addAnimation(rotateAnimation);  

animationSet.addAnimation(alphaAnimation); 

image.startAnimation(animationSet);

 

4.5. Interpolator的具体使用

       Interpolator定义了动画变化的速率,在Animations框架当中定义了一下几种Interpolator

     AccelerateDecelerateInterpolator:在动画开始与结束的地方速率改变比较慢,在中间的时候速率快。

        AccelerateInterpolator:在动画开始的地方速率改变比较慢,然后开始加速

        CycleInterpolator:动画循环播放特定的次数,速率改变沿着正弦曲线

        DecelerateInterpolator:在动画开始的地方速率改变比较慢,然后开始减速

        LinearInterpolator:动画以均匀的速率改变

 set标签上:

xml代码:

android:interpolator="@android:anim/accelerate_interpolator" 

如果一个set中包含了两种动画效果,要想这两种动画效果共享一个interpolator,可以在set标签上添加:

xml代码:

android:shareInterpolator="true"

如果不想共享一个interpolator,则可以在alpha等标签上添加。

另以上方法是在xml上处理interpolator,如果是在代码上设置 共享一个interpolator,则可以在AnimationSet设置interpolator,如果不设置共享一个interpolator则可以 alpha等的对象上面设置interpolator

java代码:

animationSet.setInterpolator(new AccelerateInterpolator());  

alphaAnimation.setInterpolator(new AccelerateInterpolator());

4.6. LayoutAnimationsContrlller的使用

LayoutAnimationsContrlller可以用于实现使多个控件按顺序一个一个的显示。

1)LayoutAnimationsContrlller用于为一个layout里面的控件,或者是一个ViewGroup里面的控件设置动画效果。

2)每一个控件都有相同的动画效果。

3)控件的动画效果可以在不同的时间显示出来。

4)LayoutAnimationsContrlller可以在xml文件当中设置,以可以在代码当中进行设置。

4.7. ListView与Animaions结合使用

1.xml当中使用LayoutAnimationsController

  1)res/anim文件夹下创建一个名为list_anim_layout.xml文件:

       android:dylay - 动画间隔时间;

       android:animationOrder - 动画执行的循序(normal:顺序,random:随机,reverse:反向显示)

       android:animation – 引用动画效果文件

xml代码:

<layoutAnimation  

    xmlns:android="http://schemas.android.com/apk/res/android" 

    android:delay="0.5" 

    android:animationOrder="normal" 

    android:animation="@anim/list_anim"/>

 

       2)在布局文件当中为ListVIew添加如下配置:

    xml代码:

android:layoutAnimation="@anim/list_anim_layout"

2.在代码当中使用LayoutAnimationsController

       对于在代码中使用LayoutAnimationsController,只不过去掉了list_anim_layout.xml这个文件,以及listview当中的

xml代码:

android:layoutAnimation="@anim/list_anim_layout" 

这句。将animation的布局设置更改到了ButtonListener代码当中进行。

 1) 创建一个Animation对象:可以通过装载xml文件,或者是直接使用Animation的构造方法创建Animation对象;

java代码:

Animation animation = (Animation)AnimationUtils.loadAnimation( 

    AnimationsActivity.this, R.anim.list_anim);

 

2) 创建LayoutAnimationController对象:

java代码:

 

LayoutAnimationController controller = new LayoutAnimationController(animation); 

3) 设置控件的显示顺序以及延迟时间:

java代码:

controller.setOrder(LayoutAnimationController.ORDER_NORMAL); 

controller.setDelay(0.5f);

 

4) ListView设置LayoutAnimationController属性:

java代码:

 

listView.setLayoutAnimation(controller);

 

4.8. AnimationListener的使用

1.AnimationListener是一个监听器,该监听器在动画执行的各个阶段会得到通知,从而调用相应的方法;

2.AnimationListener主要包括如下三个方法:

        ·onAnimationEnd(Animation animation) - 当动画结束时调用

        ·onAnimationRepeat(Animation animation) - 当动画重复时调用

        ·onAniamtionStart(Animation animation) - 当动画启动时调用

实例:

Main.xml 

xml代码:

<?xml version="1.0" encoding="utf-8"?> 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 

    android:id="@+id/layout" 

    android:orientation="vertical"  

    android:layout_width="fill_parent" 

    android:layout_height="fill_parent"> 

    <Button android:id="@+id/addButton"  

        android:layout_width="fill_parent" 

        android:layout_height="wrap_content"  

        android:layout_alignParentBottom="true" 

        android:text="添加图片" /> 

    <Button android:id="@+id/deleteButton"  

        android:layout_width="fill_parent" 

        android:layout_height="wrap_content"  

        android:layout_above="@id/addButton" 

        android:text="删除图片" /> 

    <ImageView android:id="@+id/image" 

        android:layout_width="wrap_content"  

        android:layout_height="wrap_content" 

        android:layout_centerInParent="true"  

        android:layout_marginTop="100dip" 

        android:src="@drawable/image" /> 

</RelativeLayout> 

 

 

AnimationListenerActivity.java

java代码:

package com.android.activity; 

import android.app.Activity; 

import android.os.Bundle; 

import android.view.View; 

import android.view.View.OnClickListener; 

import android.view.ViewGroup; 

import android.view.ViewGroup.LayoutParams; 

import android.view.animation.AlphaAnimation; 

import android.view.animation.Animation; 

import android.view.animation.Animation.AnimationListener; 

import android.widget.Button; 

import android.widget.ImageView; 

public class AnimationListenerActivity extends Activity { 

    private Button addButton = null

    private Button deleteButton = null

    private ImageView imageView = null

    private ViewGroup viewGroup = null

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.main); 

        addButton = (Button)findViewById(R.id.addButton); 

        deleteButton = (Button)findViewById(R.id.deleteButton); 

        imageView = (ImageView)findViewById(R.id.image); 

        //LinearLayout下的一组控件 

        viewGroup = (ViewGroup)findViewById(R.id.layout); 

        addButton.setOnClickListener(new AddButtonListener()); 

        deleteButton.setOnClickListener(new DeleteButtonListener()); 

    } 

    private class AddButtonListener implements OnClickListener{ 

        public void onClick(View v) { 

            //淡入 

            AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f); 

            animation.setDuration(1000); 

            animation.setStartOffset(500); 

            //创建一个新的ImageView 

            ImageView newImageView = new ImageView( 

                AnimationListenerActivity.this); 

            newImageView.setImageResource(R.drawable.image); 

            viewGroup.addView(newImageView, 

                new LayoutParams( 

                    LayoutParams.FILL_PARENT, 

                    LayoutParams.WRAP_CONTENT)); 

            newImageView.startAnimation(animation); 

        } 

    } 

    private class DeleteButtonListener implements OnClickListener{ 

        public void onClick(View v) { 

            //淡出 

            AlphaAnimation animation = new AlphaAnimation(1.0f, 0.0f); 

            animation.setDuration(1000); 

            animation.setStartOffset(500); 

            //为Aniamtion对象设置监听器 

            animation.setAnimationListener( 

                new RemoveAnimationListener()); 

            imageView.startAnimation(animation); 

        } 

    } 

    private class RemoveAnimationListener implements AnimationListener{ 

        //动画效果执行完时remove 

        public void onAnimationEnd(Animation animation) { 

            System.out.println("onAnimationEnd"); 

            viewGroup.removeView(imageView); 

        } 

        public void onAnimationRepeat(Animation animation) { 

            System.out.println("onAnimationRepeat"); 

        } 

        public void onAnimationStart(Animation animation) { 

            System.out.println("onAnimationStart"); 

        } 

    } 

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值