Android 动画
Andorid 平台提供了两类动画:
一:Tween(补间动画),即通过对场景里面的对象不断做图像变化(平移、缩放、旋转)产生动画效果;
二:Frame(逐帧动画),即顺序播放事先准备好的图像,跟电影类似;
Frame动画:
实现:
xml文件实现:
编码实现:
举例:xml实现过程:
定义xml文件,将该文件放在/res 下的anim或drawable目录中,文件名可以
作为资源ID 在代码中引用;
说明:
多个
android:duration="" 代表此帧持续的时间,为整数,毫秒;
例如:
提示:图片资源的存放,根据帧图片的大小放大对应的资源目录中;
编码实现:
* 创建AnimationDrawable 对象,装载xml动画文件;
* 设置控件背景资源为对应的AnimationDrawable对象;
AnimationDrawable 类中方法的介绍:
start(); 开始
stop(); 停止
setAlpha(100); 设置帧动画的透明度 (0-255)
setOneShot(); 设置是否播放一遍帧动画;
isRunning(); 是否正在播放
isOneShot(); 是否只播放一遍
getNmberOfFrames(); 返回帧动画的帧数,即
getFrame(); 根据索引得到指定帧的Drawable对象; 索引0开始;
getDuration(); 获得指定帧停留时间;
addFrame(); 向AnimationDrawable对象中添加新的帧;
案例:小鸟飞翔,撞击并发出声音:
res/anim 下的动画文件:
布局文件如下:
主程序入口:
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","开始播放音效了..."); } } }; }