当前位置: 代码迷 >> Android >> android卡通片——Frame by Frame Animation
  详细解决方案

android卡通片——Frame by Frame Animation

热度:86   发布时间:2016-04-28 07:49:49.0
android动画——Frame by Frame Animation

在写Frame by Frame Animation之前先介绍一下android中支持的动画类型。android有两种机制让用户创建简单的动画——tweened animation 和 frame by frame animation 。 其中tweened animation 实现 view 的诸如 移动 、大小变化、旋转等;frame by frame animation  是加载一系列的图片顺序的播放他们。处理 tweened animation的api 在包 android.view.animation中,而处理 frame by frame animation 的 在 AnimationDrawable 中。

下面重点说一下frame by frame animation (帧动画):

  Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称为逐帧动画。Frame动画可以被定义在XML文件中,也可以完全编码实现。

如果被定义在XML文件中,我们可以放置在/res下的anim或drawable目录中,文件名可以作为资源ID在代码中引用;如果由完全由编码实现,我们需要使用到AnimationDrawable对象。

1、将动画定义在xml文件中

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="false"    android:id="@+id/frame_anim_list" >    <item        android:drawable="@drawable/ting_frame_0"        android:duration="50">    </item>    <item        android:drawable="@drawable/ting_frame_0"        android:duration="50">    </item>    <item        android:drawable="@drawable/ting_frame_1"        android:duration="50">    </item>    <item        android:drawable="@drawable/ting_frame_2"        android:duration="50">    </item>    <item        android:drawable="@drawable/ting_frame_3"        android:duration="500">    </item>    <item        android:drawable="@drawable/ting_frame_4"        android:duration="50">    </item></animation-list>

其中<animation-list>元素是必须的,并且必须要作为根元素,可以包含一或多个<item>元素;android:onshot如果定义为true的话,此动画只会执行一次,如果为false则一直循环。一个<item>元素代表一帧动画,android:drawable指定此帧动画所对应的图片资源,android:druation代表此帧持续的时间,整数,单位为毫秒。


2、硬编码实现逐帧动画

private final int[] frames = { R.drawable.ting_frame_0,            R.drawable.ting_frame_1, R.drawable.ting_frame_2,            R.drawable.ting_frame_3, R.drawable.ting_frame_4 };private void createAnim() {        mAd = new AnimationDrawable();        for (int i = 0; i < frames.length; i++) {            mAd.addFrame(getResources().getDrawable(frames[i]), 300);        }        mAd.setOneShot(false);    }
其中mAd是个DrawableAnimation对象。方法setOneShot(false)同xml中的android:oneShot="false" 。

看了半天,发现没有实例是最tmdt的事,有兴趣的朋友可以继续看下面的实例。 首先,我们先准备几张图片命名为 ting_frame_0.png 、ting_frame_1.png 、ting_frame_2.png 、ting_frame_3.png 、 ting_frame_4.png 放到drawable目录下 , 并在drawable目录下创建文件 frame_by_frame_anim.xml , 文件内容如下 :

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="false"    android:id="@+id/frame_anim_list" >    <item        android:drawable="@drawable/ting_frame_0"        android:duration="300">    </item>    <item        android:drawable="@drawable/ting_frame_0"        android:duration="300">    </item>    <item        android:drawable="@drawable/ting_frame_1"        android:duration="300">    </item>    <item        android:drawable="@drawable/ting_frame_2"        android:duration="300">    </item>    <item        android:drawable="@drawable/ting_frame_3"        android:duration="300">    </item>    <item        android:drawable="@drawable/ting_frame_4"        android:duration="300">    </item></animation-list>
layout目录下创建两个xml文件 分别为 activity_main.xml , frame_anim_layout.xml

activity_main.xml主要定义了一些指示操作的view(没用到的view可以删除),其内容如下:

<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/frame_anim_btn"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="@string/frame_animation" />    <Button        android:id="@+id/button2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Button" />    <Button        android:id="@+id/button3"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Button" />    <Button        android:id="@+id/button4"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Button" />    <Button        android:id="@+id/button5"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Button" />    <Button        android:id="@+id/button6"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Button" />    <Button        android:id="@+id/button7"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Button" /></LinearLayout>
 frame_anim_layout.xml , 定义了用于显示动画容器  ImageView ,其内容如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/root_container"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <!-- android:background="@drawable/frame_by_frame_anim" -->    <ImageView        android:id="@+id/frame_image"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:contentDescription="@string/app_name"        android:background="@drawable/frame_by_frame_anim"/></LinearLayout>

AndroidManifest.xml的内容如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.zt.xy.animation"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="10"        android:targetSdkVersion="15" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/title_activity_main" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity android:name="FrameAnimActivity"></activity>    </application></manifest>
同样也使用了两个activity , 它们分别是 MainActivity  和  FrameAnimActivity

MainActivity.java的内容如下:

import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {    private Button mFrameAnim;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init() {        mFrameAnim = (Button) findViewById(R.id.frame_anim_btn);        mFrameAnim.setOnClickListener(this);    }    public void onClick(View v) {        Intent tarIntent;        switch (v.getId()) {        case R.id.frame_anim_btn:            tarIntent = new Intent(this, FrameAnimActivity.class);            this.startActivity(tarIntent);            break;        }    }}

当点击 “Frame Animation ” 按钮时启动显示动画的activity 。

下面是显示动画的activity   FrameAnimActivity.java :

import android.app.Activity;import android.graphics.drawable.AnimationDrawable;import android.os.Bundle;import android.widget.ImageView;public class FrameAnimActivity extends Activity {    private ImageView mFrameImg;    AnimationDrawable mAd;    private final int[] frames = { R.drawable.ting_frame_0,            R.drawable.ting_frame_1, R.drawable.ting_frame_2,            R.drawable.ting_frame_3, R.drawable.ting_frame_4 };    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.frame_anim_layout);        init();        try {            mAd = (AnimationDrawable) mFrameImg.getBackground();        } catch (ClassCastException e) {            mAd = null;        }        // createAnim();        // mFrameImg.setBackground(mAd);    }    private void createAnim() {        mAd = new AnimationDrawable();        for (int i = 0; i < frames.length; i++) {            mAd.addFrame(getResources().getDrawable(frames[i]), 300);        }        mAd.setOneShot(false);    }    @Override    public void onResume() {        super.onResume();        if (mAd != null) {            mAd.start();        }    }    @Override    public void onPause() {        super.onPause();        if (mAd != null) {            mAd.stop();        }    }    private void init() {        mFrameImg = (ImageView) findViewById(R.id.frame_image);    }}
好了,运行一下,大功告成。

以上使用的是xml中定义的动画,若想硬编码实现逐帧动画,则将onCreate函数中修改为如下内容:

public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.frame_anim_layout);        init();//        try {//            mAd = (AnimationDrawable) mFrameImg.getBackground();//        } catch (ClassCastException e) {//            mAd = null;//        }         createAnim();         mFrameImg.setBackground(mAd);    }
再将 frame_anim_layout.xml中的  android:background="@drawable/frame_by_frame_anim"  删除即可。

  相关解决方案