Android 之 Frame逐帧动画

Android 动画


Andorid 平台提供了两类动画:
一:Tween(补间动画),即通过对场景里面的对象不断做图像变化(平移、缩放、旋转)产生动画效果;
二:Frame(逐帧动画),即顺序播放事先准备好的图像,跟电影类似;

Frame动画:
实现:
  xml文件实现:
  编码实现:

举例:xml实现过程:

    定义xml文件,将该文件放在/res 下的anim或drawable目录中,文件名可以
作为资源ID 在代码中引用;
说明:<animation-list>元素是必须的,并且必须作为根元素,可以包含一个或
多个<item>元素;

<animation-list>属性:android:oneshot="" 是否循环播放,false表示循环,可选,默认false
<item>元素属性:android:drawble="" 指定此帧动画所对应的图片资源;
android:duration="" 代表此帧持续的时间,为整数,毫秒;

例如:

提示:图片资源的存放,根据帧图片的大小放大对应的资源目录中;


编码实现:
  * 创建AnimationDrawable 对象,装载xml动画文件;
  * 设置控件背景资源为对应的AnimationDrawable对象;

AnimationDrawable 类中方法的介绍:
start();  开始
stop();   停止
setAlpha(100);  设置帧动画的透明度 (0-255)
setOneShot(); 设置是否播放一遍帧动画;
isRunning();  是否正在播放
isOneShot();   是否只播放一遍
getNmberOfFrames();  返回帧动画的帧数,即<item> 标签数;
getFrame();  根据索引得到指定帧的Drawable对象; 索引0开始;
getDuration(); 获得指定帧停留时间;
addFrame(); 向AnimationDrawable对象中添加新的帧;




案例:小鸟飞翔,撞击并发出声音:


res/anim 下的动画文件:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >

 	<item android:drawable="@drawable/bird00" android:duration="180"></item>
 	<item android:drawable="@drawable/bird01" android:duration="180"></item>
 	<item android:drawable="@drawable/bird02" android:duration="180"></item>
 	<item android:drawable="@drawable/bird03" android:duration="180"></item>
 	<item android:drawable="@drawable/bird04" android:duration="180"></item>
 	<item android:drawable="@drawable/bird05" android:duration="180"></item>
 	<item android:drawable="@drawable/bird06" android:duration="180"></item>
 	<item android:drawable="@drawable/bird07" android:duration="180"></item>
 	<item android:drawable="@drawable/bird08" android:duration="180"></item>
 	<item android:drawable="@drawable/bird09" android:duration="180"></item>
 	<item android:drawable="@drawable/bird10" android:duration="180"></item>
 	
 	
</animation-list>



布局文件如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <!-- 自定义控件 -->
    <com.sun.frame.MyImageView
        android:id="@+id/imageview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>



主程序入口:
package com.sun.frame;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends Activity {

	private ImageView imageview ;
	private AnimationDrawable ad; // 
	
	// 数据初始化
	public void init(){
		
		imageview = (ImageView) findViewById(R.id.imageview1);
	
	}
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		init();
		imageview.setOnClickListener(listener);
	}
	
	// 点击事件监听器
	private View.OnClickListener listener = new View.OnClickListener() {
		public void onClick(View v) {
			
			if(ad.isRunning()){
				ad.stop();
			}else
			ad.start();
		}
	};

	/**
	 * Activity 呈现给用户的时候调用的
	 */
	public void onWindowFocusChanged(boolean hasFocus) {
		super.onWindowFocusChanged(hasFocus);
		ad = (AnimationDrawable) getResources().getDrawable(R.anim.frame);
		imageview.setBackgroundDrawable(ad);
	}
}


自定义视图控件,便于控制图片的变化:
package com.sun.frame;

import java.lang.reflect.Field;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;

public class MyImageView extends ImageView {

	public AnimationDrawable animationDrawable;
	private Field field; // 领域对象
	private SoundPool sp;
	private int music;

	/**
	 * 初始化数据
	 * 
	 * @param context
	 * @param attrs
	 */
	public MyImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		Log.i("msg","MyImageView构造方法...");
		/* 参数:
		 * 1、 播放数据流的最大个数 
		 * 2、数据流类型
		 * 3、声音质量
		 */
		sp = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
		music = sp.load(context, R.raw.a2, 1);
		
//		Log.i("msg","MyImageView构造方法...");
	}

	/**
	 * 画一次图调用一次 功能:用于监听每帧动画的播放状态
	 */
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Log.i("msg", "onDraw()...");
		try {
			field = AnimationDrawable.class.getDeclaredField("mCurFrame");
			field.setAccessible(true); // 设置可以访问

			// 获取mCurFrame变量的当前值
			int curFrame = field.getInt(animationDrawable);
			if (curFrame == 29) {
				
				//animationDrawable.stop(); // 停止播放
				
				// 播放音乐特效
				sp.play(music, 1, 1, 0, 0, 1);
				Log.i("msg", "特效出来啦...");
				// 设置动画的播放位置
				//field.setInt(animationDrawable, 0); // 从0 开始
			}else{
				sp.pause(music);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}



对自定义控件的使用,以及对应的效果:
package com.sun.frame;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

/**
 * 自定义控件的使用
 * @author Administrator
 *
 *注意:在AnimationDrawable 类中有一个mCurFrame变量,int型,保存当前动画的
 *播放位置;改变量为私有的,所以只能通过反射机制读写private变量
 *
 */
public class UserFrameActivity extends Activity {

	private MyImageView image;
	private AnimationDrawable ad; // 控制动画
	private SoundPool sp ; //音效池 -- 小鸟叫
	private int music; // 音乐

	// 程序入口
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.code_frame);

		// 获取控件对象,该对象为自定义对象
		image = (MyImageView) findViewById(R.id.imageview1);
		image.setOnClickListener(listener);

		// 音效初始化
		sp = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
		music = sp.load(this, R.raw.a3,1); //加载音乐
		Log.i("msg", "onCreate()...");
	}


	/**
	 * Activity 呈现给用户时调用
	 */
	public void onWindowFocusChanged(boolean hasFocus) {
		// TODO Auto-generated method stub
		super.onWindowFocusChanged(hasFocus);
		Log.i("msg","UserFrameActivity.onWindowFocusChanged()...");
		image.setBackgroundResource(R.anim.frame_c); // 设置背景资源
		ad = (AnimationDrawable) image.getBackground();
		image.animationDrawable = ad; // 同步
		ad.start();
		sp.play(music, 1, 1, 0, -1, 1);
	}



	// 点击监听器
	private OnClickListener listener = new OnClickListener() {

		public void onClick(View v) {

			if(ad.isRunning()){
				ad.stop();
				sp.pause(music); // 停止音效	
				Log.i("msg", "音效停止了...");
			}else{
				ad.start();
				sp.resume(music); //(music, 1, 1, 0, -1, 1); // 播放音效
				Log.i("msg","开始播放音效了...");
			}
		}
	};
}

猜你喜欢

转载自sunzone.iteye.com/blog/1998083