编程回忆之Android回忆(AnimationDrawable的使用)

AnimationDrawable的使用

Drawable animation可以加载Drawable资源实现帧动画。AnimationDrawable是实现Drawable animations的基本类。

一、什么是AnimationDrawable

AnimationDrawable代表一个动画,首先来说说补间动画,补间动画就是设置图片的首末状态,在指定的时间里面完成动画的变化。

定义补间动画的XML资源以<set>元素作为根元素,该元素内可以指定如下4个属性:

alpha:设置透明度的改变

scale:设置图片进行缩放的改变

translate:设置图片进行位移的变化。

route:设置图片进行旋转。

二、如何使用AnimationDrawable

推荐用XML文件的方法实现Drawable动画,不推荐在代码中实现。定义图片的XML文件应该放在/res/anim路径下,设置补间动画的思路很简单:设置一张图片的开始状态,再设置图片的结束状态,最后设置动画的持续时间和变化。

三、AnimationDrawable的xml定义

首先定义一个用于播放的xml

<?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/on_001"
        android:duration="100"/>

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

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

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

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

    <item
        android:drawable="@drawable/on_006"
        android:duration="100"/>
</animation-list>

定义完后使用代码调用它

AnimationDrawable ad = (AnimationDrawable) getResources().getDrawable(
R.drawable.bootanimation);
mView.setBackgroundDrawable(ad);
ad.start();

四、AnimationDrawable的代码实现

在具体实现中,需要预先准备了15张单帧动画图像,分别命名为image1到image15,并存放在工程的res/drawable目录下。然后可以通过如下方法将每一帧的图像加载到AnimationDrawable对象中。

 

 mAnimationDrawable = new AnimationDrawable();
         for (int i = 1; i <= 15; i++) {
            int resourcesId = getResources().getIdentifier("image"+i, "drawable", mContext.getPackageName());
            mDrawable = getResources().getDrawable(resourcesId);
            mAnimationDrawable.addFrame(mDrawable, 500);
        }


五、AnimationDrawable使用的封装

在项目中,个别项目需要多次使用到AnimationDrawable,这时候可以对AnimationDrawable的使用进行封装

1、对AnimationDrawable属性的封装

package com.lyh.common.anim;

/**
 * 
 * 类名:AnimationAttribute
 * 
 * @author lyh
 */
public class AnimationAttribute {

	private String drawable; // 图片资源名称
	private String oneShot; // 是否重复播放的参数
	private String duration; // 播放间隔时间的参数

	public String getDrawable() {
		return drawable;
	}

	public void setDrawable(String drawable) {
		this.drawable = drawable;
	}

	public String getOneShot() {
		return oneShot;
	}

	public void setOneShot(String oneShot) {
		this.oneShot = oneShot;
	}

	public String getDuration() {
		return duration;
	}

	public void setDuration(String duration) {
		this.duration = duration;
	}
}


2、xml解析类XMLContentHandler

package com.lyh.common.anim;

import java.util.ArrayList;

import java.util.List;

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

public class XMLContentHandler extends DefaultHandler {

	private List<AnimationAttribute> persons = null;
	private AnimationAttribute currentPerson;
	private String tagName = null;// 当前解析的元素标签

	public List<AnimationAttribute> getPersons() {
		return persons;
	}

	/**
	 * 接收文档的开始的通知。
	 */

	@Override
	public void startDocument() throws SAXException {
		persons = new ArrayList<AnimationAttribute>();
	}

	/**
	 * 接收字符数据的通知。
	 **/
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if (tagName != null) {
			// String data = new String(ch, start, length);
			if (tagName.equals("name")) {
				// this.currentPerson.setName(data);
			} else if (tagName.equals("age")) {
				// this.currentPerson.setAge(Short.parseShort(data));
			}
		}
	}

	/**
	 * 接收元素开始的通知。 参数意义如下:
	 * 
	 * @param namespaceURI
	 *            :元素的命名空间
	 * @param localName
	 *            :元素的本地名称(不带前缀)
	 * @param qName
	 *            :元素的限定名(带前缀)
	 * @param atts
	 *            :元素的属性集合
	 */

	@Override
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes atts) throws SAXException {
		currentPerson = new AnimationAttribute();
		if (localName.equals("item")) {
			currentPerson.setDrawable(atts.getValue("android:drawable"));
			currentPerson.setDuration(atts.getValue("android:duration"));
		} else if (localName.equals("animation-list")) {
			currentPerson.setOneShot(atts.getValue("android:oneshot"));
		}

		this.tagName = localName;

	}

	/**
	 * 接收文档的结尾的通知。 参数意义如下:
	 * 
	 * @param uri
	 *            :元素的命名空间
	 * @param localName
	 *            :元素的本地名称(不带前缀)
	 * @param name
	 *            :元素的限定名(带前缀)
	 */

	@Override
	public void endElement(String uri, String localName, String name)
			throws SAXException {
		if (localName.equals("item")) {
			persons.add(currentPerson);
			currentPerson = null;
		}
		this.tagName = null;
	}
}


3、动画播放类

package com.lyh.common.anim;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;

/**
 * 
 * 类名:PlayAnimation
 * 
 * @author lyh
 * 
 */
public class PlayAnimation extends AnimationDrawable {
	private Context context;
	private final String FOLDERNAME = "drawable";

	private Map<String, Drawable> resMap;

	public PlayAnimation(Context context) {
		WeakReference<Context> mCt = new WeakReference<Context>(context);
		this.context = mCt.get();

		if (resMap == null) {
			resMap = new HashMap<String, Drawable>();
		}
	}

	/**
	 * 
	 * 函数名称 : startAnimationResourceFileName 功能描述 : 播放动画,用文件名加载动画资源的启动方式
	 * 参数及返回值说明:
	 * 
	 * @param imgAnimation
	 *            承载动画播放的控件
	 * @param fileNameList
	 *            文件名的集合
	 * @param duration
	 *            动画播放间隔时间
	 * @param oneShot
	 *            重复播放动画,ture不重复,false重复
	 * 
	 */
	public void startAnimationResourceFileName(ImageView imgAnimation,
			List<String> fileNameList, int duration, boolean oneShot) {
		addResourceFileName(fileNameList, duration, oneShot);
		imgAnimation.setBackgroundDrawable(this);
		this.start();
	}

	/**
	 * 
	 * 函数名称 : startAnimationResourceId 功能描述 : 播放动画,用资源id加载动画资源的启动方式
	 * 
	 * 参数及返回值说明:
	 * 
	 * @param imgAnimation
	 *            承载动画播放的控件
	 * @param resourceList
	 *            播放资源id集合
	 * @param duration
	 *            动画播放间隔时间
	 * @param oneShot
	 *            重复播放动画,ture不重复,false重复
	 * 
	 */
	public void startAnimationResourceId(ImageView imgAnimation,
			List<Integer> resourceList, int duration, boolean oneShot) {
		addResourceId(resourceList, duration, oneShot);
		imgAnimation.setBackgroundDrawable(this);
		this.start();
	}

	/**
	 * 
	 * 函数名称 : startAssetsResouurce 功能描述 : 播放动画,用asstes文件夹下解析xml文件,加载动画资源的启动方式
	 * 参数及返回值说明:
	 * 
	 * @param imgAnimation
	 *            承载动画播放的控件
	 * @param fileName
	 *            assets的相对路径
	 * 
	 *            修改记录: 日期 :2013-8-16 下午2:13:59 修改人: 描述 :
	 * 
	 */
	public void startAssetsResource(ImageView imgAnimation, String fileName) {
		addAssetsResource(fileName);
		imgAnimation.setBackgroundDrawable(this);
		this.start();
	}

	/**
	 * 从sd卡读取资源,播放动画
	 * @param imgAnimation
	 * @param fileName
	 */
	public void startSdcardResource(ImageView imgAnimation, String fileName) {
		addSdcardResource(fileName);
		imgAnimation.setBackgroundDrawable(this);
		this.start();
	}

	/**
	 * 
	 * 函数名称 : addResourceFileName 功能描述 : 用文件名批量添加动画资源 参数及返回值说明:
	 * 
	 * @param fileNameList
	 *            文件名的集合
	 * @param duration
	 *            动画播放间隔时间
	 * @param oneShot
	 *            重复播放动画,ture不重复,false重复
	 * 
	 */
	public void addResourceFileName(List<String> fileNameList, int duration,
			boolean oneShot) {
		for (int i = 0; i < fileNameList.size(); i++) {
			int id = context.getResources().getIdentifier(
					context.getPackageName() + ":" + FOLDERNAME + "/"
							+ fileNameList.get(i), null, null);
			this.addFrame(context.getResources().getDrawable(id), duration);
		}

		this.setOneShot(false);
	}

	/**
	 * 
	 * 函数名称 : addResourceId 功能描述 : 用文件名单个添加动画资源 参数及返回值说明:
	 * 
	 * @param fileName
	 *            文件名
	 * @param duration
	 *            动画播放间隔时间
	 * @param oneShot
	 *            重复播放动画,ture不重复,false重复
	 * 
	 */
	public void addResourceFileName(String fileName, int duration,
			boolean oneShot) {
		int id = context.getResources().getIdentifier(
				context.getPackageName() + ":" + FOLDERNAME + "/" + fileName,
				null, null);
		this.addFrame(context.getResources().getDrawable(id), duration);
		this.setOneShot(false);
	}

	/**
	 * 
	 * 函数名称 : addResourceId 功能描述 : 用资源id添加动画资源 参数及返回值说明:
	 * 
	 * @param resourceList
	 *            资源集合
	 * @param duration
	 *            动画播放间隔时间
	 * @param oneShot
	 *            重复播放动画,ture不重复,false重复
	 */
	public void addResourceId(List<Integer> resourceList, int duration,
			boolean oneShot) {
		for (int i = 0; i < resourceList.size(); i++) {
			this.addFrame(
					context.getResources().getDrawable(resourceList.get(i)),
					duration);
		}
		this.setOneShot(oneShot);
	}

	/**
	 * 
	 * 函数名称 : addAssetsResource 功能描述 : 用asstes文件下xml文件添加动画资源 参数及返回值说明:
	 * 
	 * @param folderName
	 *            文件在asstes的相对路径
	 */
	public void addAssetsResource(String fileName) {
		try {
			List<AnimationAttribute> list = anaysisXml(true, fileName);

			if (resMap.get(fileName + 0) == null) {
				String path = fileName.substring(0, fileName.lastIndexOf("/"))
						+ "/";
				for (int i = 0; i < list.size(); i++) {
					InputStream inputStream2 = context.getResources()
							.getAssets().open(path + list.get(i).getDrawable());
					Drawable drawable = Drawable.createFromStream(inputStream2,
							null);
					this.addFrame(drawable,
							Integer.valueOf(list.get(i).getDuration()));
					this.setOneShot(Boolean.valueOf(list.get(i).getOneShot()));
					resMap.put(fileName + i, drawable);
				}
			} else {
				for (int i = 0; i < list.size(); i++) {
					this.addFrame(resMap.get(fileName + i),
							Integer.valueOf(list.get(i).getDuration()));
					this.setOneShot(Boolean.valueOf(list.get(i).getOneShot()));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 读取sd卡图片资源
	 * 
	 * @param fileName
	 */
	public void addSdcardResource(String fileName) {
		List<AnimationAttribute> list = anaysisXml(false, fileName);

		String path = fileName.substring(0, fileName.lastIndexOf("/")) + "/";

		for (int i = 0; i < list.size(); i++) {
			Drawable drawable = Drawable.createFromPath(path
					+ list.get(i).getDrawable());
			this.addFrame(drawable, Integer.valueOf(list.get(i).getDuration()));
			this.setOneShot(Boolean.valueOf(list.get(i).getOneShot()));
		}
	}

	/**
	 * 解析assets目录下的xml动画文件
	 * 
	 * @param fileName
	 * @return
	 */
	public List<AnimationAttribute> anaysisXml(boolean assets, String fileName) {
		try {
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser saxParser;
			saxParser = spf.newSAXParser();
			XMLContentHandler handler = new XMLContentHandler();
			InputStream inputStream = null;
			if (assets) {
				inputStream = this.context.getResources().getAssets()
						.open(fileName);
			} else {
				inputStream = new FileInputStream(fileName);
			}
			saxParser.parse(inputStream, handler);
			inputStream.close();
			List<AnimationAttribute> list = handler.getPersons();
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}


 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值