在上一篇博客中,我们总结了Android动画的补间动画的基本用法,如果你还没了解,推荐您了解一下 Android动画学习总结---上
Frame Animation(逐帧动画)
现在让我们来谈谈
Frame Animation(逐帧动画),顾名思义逐帧动画就是预先准备一系列的图片集合,再将它们按照顺序播放出来就形成了逐帧动画。
逐帧动画的根元素为animation-list,其有一项属性oneshot的值为布尔值类型,若true表示不循环播放,若为false表示循环播放。在这个根元素里面可以包含若干个item元素,每个item必须设置duration属性值,表示此帧持续多少秒,如果不设置编译的时候就会报错。
第一步,首先在工程中的drawable文件夹(如果没有此文件夹请自行创建一个)创建一个资源文件,将其命名为frame.xml,如图所示
第二步,开始写代码啦,在frame.xml文件的代码如下,一个animation-list的根元素,里面有若干个item元素。记得设置oneshot和duration的值。在这里我将oneshot设置为true表示不循环播放,duration设置为100表示每0.1秒播放一帧动画
第三部,设置布局文件在一个垂直的线性布局中放置两个button和一个imageview。
这个布局的预览图如下所示
![](https://img-blog.csdn.net/20151004223206913?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第四步,咋们就可以在Activity中加载刚才写好的资源文件啦。
接下来看看效果图
资源文件加载动画的用法
开始之前请确定mipmap文件里有以下资源图片(如果没有,我会在下面的源代码demo中提供)
第一步,首先在工程中的drawable文件夹(如果没有此文件夹请自行创建一个)创建一个资源文件,将其命名为frame.xml,如图所示
第二步,开始写代码啦,在frame.xml文件的代码如下,一个animation-list的根元素,里面有若干个item元素。记得设置oneshot和duration的值。在这里我将oneshot设置为true表示不循环播放,duration设置为100表示每0.1秒播放一帧动画
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item
android:drawable="@mipmap/edward1"
android:duration="100" />
<item
android:drawable="@mipmap/edward2"
android:duration="100" />
<item
android:drawable="@mipmap/edward3"
android:duration="100" />
<item
android:drawable="@mipmap/edward4"
android:duration="100" />
<item
android:drawable="@mipmap/edward5"
android:duration="100" />
<item
android:drawable="@mipmap/edward6"
android:duration="100" />
<item
android:drawable="@mipmap/edward7"
android:duration="100" />
<item
android:drawable="@mipmap/edward8"
android:duration="100" />
<item
android:drawable="@mipmap/edward9"
android:duration="100" />
<item
android:drawable="@mipmap/edward10"
android:duration="100" />
<item
android:drawable="@mipmap/edward11"
android:duration="100" />
<item
android:drawable="@mipmap/edward12"
android:duration="100" />
<item
android:drawable="@mipmap/edward13"
android:duration="100" />
<item
android:drawable="@mipmap/edward14"
android:duration="100" />
<item
android:drawable="@mipmap/edward15"
android:duration="100" />
<item
android:drawable="@mipmap/edward16"
android:duration="100" />
<item
android:drawable="@mipmap/edward17"
android:duration="100" />
<item
android:drawable="@mipmap/edward18"
android:duration="100" />
<item
android:drawable="@mipmap/edward19"
android:duration="100" />
<item
android:drawable="@mipmap/edward20"
android:duration="100" />
<item
android:drawable="@mipmap/edward21"
android:duration="100" />
<item
android:drawable="@mipmap/edward22"
android:duration="100" />
<item
android:drawable="@mipmap/edward23"
android:duration="100" />
<item
android:drawable="@mipmap/edward24"
android:duration="100" />
<item
android:drawable="@mipmap/edward25"
android:duration="100" />
<item
android:drawable="@mipmap/edward26"
android:duration="100" />
<item
android:drawable="@mipmap/edward27"
android:duration="100" />
</animation-list>
第三部,设置布局文件在一个垂直的线性布局中放置两个button和一个imageview。
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical">
<Button
android:id="@+id/one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="click"
android:text="开始" />
<Button
android:id="@+id/two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="click"
android:text="停止" />
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:background="@drawable/frame" />
<!--注意此处背景一定要设置为动画资源文件,否则会报错-->
</LinearLayout>
这个布局的预览图如下所示
第四步,咋们就可以在Activity中加载刚才写好的资源文件啦。
package sms.edward.per.myapplication;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
/**
* description:资源文件加载
* <p/>
* author:Edward
* <p/>
* 2015/10/4
*/
public class TwoActivity extends Activity {
private ImageView imageView;
private AnimationDrawable animationDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
imageView = (ImageView) findViewById(R.id.image_view);
//注意由于的资源文件中已经将oneshot设置为true所以你
// 将会看到动画播放完毕之后就停止了(也就是不会循环播放)
animationDrawable = (AnimationDrawable) imageView.getBackground();
}
public void click(View v) {
switch (v.getId()) {
case R.id.one:
//开始动画
animationDrawable.start();
break;
case R.id.two:
//停止动画
animationDrawable.stop();
break;
}
}
}
接下来看看效果图
Java编码加载动画的用法
在编码的过程如果不想创建资源文件(指得是刚才创建的frame.xml文件)那该怎么办?
这时候我们就可以使用代码的方式来定义动画的播放顺序。
首先需要介绍一下前面已经用过的AnimationDrawable这个类
这是一个加载Drawable动画资源类。我们将一系列动画的每一帧动画转化为Drawable类,再将其添加进AnimationDrawable的addFrame方法中即可。如果还不太懂可以看下面的代码。
第一步,先设置布局文件,这个布局文件与上面的布局文件几乎一样,唯一的区别就是ImageView的
android:background="@drawable/frame"被删除。(删掉它也正常,咋们都用代码来代替frame.xml文件,那还设置background干嘛!)
好啦,android的逐帧动画的基本用法已经总结完毕,还是由于篇幅的关系,剩下Property Animation属性动画我将会在下一遍博客中总结。如果您还有兴趣请期待我的下一篇博客Android动画学习总结---下。
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical">
<Button
android:id="@+id/one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="click"
android:text="开始" />
<Button
android:id="@+id/two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="click"
android:text="停止" />
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal" />
</LinearLayout>
预览图就不贴了,与上面的一样
第二步,直接就在Activity中写代码啦,这里主要说明getIdentifier这个方法。这是一个获取动态ID的方法,资源图片在mipmap文件夹中编译的时候系统会对每张图片生一个唯一的资源ID,这个getIdentifier就是用来获取这个唯一ID的。我们得到这个唯一ID后将其转换为Bitmap类再转换为Drawable类就行了。
效果图如下所示
package sms.edward.per.myapplication;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
/**
* description:编码方式加载
* <p/>
* author:Edward
* <p/>
* 2015/10/4
*/
public class OneActivity extends Activity {
private ImageView imageView;
private AnimationDrawable animationDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
imageView = (ImageView) findViewById(R.id.image_view);
animationDrawable = new AnimationDrawable();
//总共有27张图片
for (int i = 1; i <= 27; i++) {
//动态获取资源ID,第一个参数是资源名,第二个参数是资源类型例如drawable,string等,第三个参数包名
Resources resources=getResources();
int imageId = resources.getIdentifier("edward" + i, "mipmap", getPackageName());
//以下两行主要将bitmap转换为drawable
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imageId);
Drawable drawable = new BitmapDrawable(getResources(), bitmap);
//将每一帧动画添加进AnimationDrawable的addFrame方法中。
animationDrawable.addFrame(drawable, 100);
}
//true表示不循环播放,false表示循环播放
animationDrawable.setOneShot(false);
//可以使用setBackgroupd不过好像提示最低版本需要16以上才能使用
imageView.setBackgroundDrawable(animationDrawable);
}
public void click(View v) {
switch (v.getId()) {
case R.id.one:
//开始动画
animationDrawable.start();
break;
case R.id.two:
//结束动画
animationDrawable.stop();
break;
}
}
}
效果图如下所示