Android 动画系列:
Android 动画–帧动画(Frame Animation)
Android 动画–补间动画(Tween Animation)
一. Android 动画分类
Android 动画可分以下两类:View 动画 和 属性动画
1. View 动画(View Animation)
View Animation又可分为:帧动画(Frame Animation)和补间动画(Tween Animation)
1.1 帧动画(Frame Animation)
帧动画原理比较简单,就是把动画过程的每张静态图顺序的组织在一起,然后依次的播放这个图片集合,形成一种动画的效果,这个原理和放动画片的原理一样。
一般帧动画是通过xml资源文件实现更加容易,在res/drawable文件夹,使用 采用元素来定义不同的帧,并且可以设置每帧的持续时间。
当然也可以在Java代码中定义动画帧,使用的是AnimationDrawable类,可以使用addFrame(Drawalbe frame, int duration)
向AnimationDrawable动画对象中添加相应的帧。
其实无论哪种方式,实现frame都要使用AnimationDrawable,来看看这个类的继承体系:
简单例子:
先看效果
将使用两种方式去展现帧动画的使用,分别为:
方式一:xml创建动画 (推荐)
方式二:使用addFrame(Drawable frame, int duration) 动态添加;
(1) 先创建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/wifi_1" android:duration="200"/>
<item android:drawable="@drawable/wifi_2" android:duration="200"/>
<item android:drawable="@drawable/wifi_3" android:duration="200"/>
<item android:drawable="@drawable/wifi_4" android:duration="200"/>
<item android:drawable="@drawable/wifi_5" android:duration="200"/>
<item android:drawable="@drawable/wifi_6" android:duration="200"/>
</animation-list>
(2)主布局activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cjl.animationtest.MainActivity">
<ImageView
android:id="@+id/img_wifi"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:src="@drawable/anim_frame_wifi" />
<Button
android:id="@+id/btn_toggle_wifi"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:gravity="center"
android:layout_marginTop="30dp"
android:background="@color/colorAccent"
android:layout_below="@+id/img_wifi"
android:text="Start"
android:textColor="@android:color/white"
android:textSize="24sp" />
</RelativeLayout>
以上关键就是给 ImageView 设置 src 为我们第一步定义的帧动画anim_frame_wifi.xml
(3) 播放动画
package com.cjl.animationtest;
import android.graphics.drawable.AnimationDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private ImageView mImgWifi;
private AnimationDrawable mWifiAnimDrawable;
private boolean mIsShowAnim = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImgWifi = (ImageView) findViewById(R.id.img_wifi);
Button btnToggleWifi = (Button) findViewById(R.id.btn_toggle_wifi);
//方式一:使用xml动画资源
//获取动画对象,该动画就是我们在xml设置的src
mWifiAnimDrawable = (AnimationDrawable) mImgWifi.getDrawable();
//方式二:使用使用addFrame(Drawable frame, int duration) 动态添加帧动画
//mWifiAnimDrawable = new AnimationDrawable();
//mWifiAnimDrawable.addFrame(getResources().getDrawable(R.drawable.wifi_1), 200);
//mWifiAnimDrawable.addFrame(getResources().getDrawable(R.drawable.wifi_2), 200);
//mWifiAnimDrawable.addFrame(getResources().getDrawable(R.drawable.wifi_3), 200);
//mWifiAnimDrawable.addFrame(getResources().getDrawable(R.drawable.wifi_4), 200);
//mWifiAnimDrawable.addFrame(getResources().getDrawable(R.drawable.wifi_5), 200);
//mWifiAnimDrawable.addFrame(getResources().getDrawable(R.drawable.wifi_6), 200);
//设置为循环播放
//mWifiAnimDrawable.setOneShot(false);
//mImgWifi.setBackgroundDrawable(mWifiAnimDrawable);
btnToggleWifi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mIsShowAnim){
stopAnimation();
mIsShowAnim = false;
} else {
startAnimation();
mIsShowAnim = true;
}
}
});
}
private void startAnimation(){
if(mWifiAnimDrawable != null) {
mWifiAnimDrawable.start();
}
}
private void stopAnimation(){
if(mWifiAnimDrawable != null) {
mWifiAnimDrawable.stop();
}
}
}
记录一个平时经常用到的方法, 判断帧动画播放是否播放到某一帧:
该方法可在自定义frame 动画时使用
private boolean isLastFrame(){
try {
Field field = AnimationDrawable.class.getDeclaredField("mCurFrame");
field.setAccessible(true);
int currentFrame = field.getInt(mWifiAnimDrawable);
if (currentFrame == mWifiAnimDrawable.getNumberOfFrames() - 1) {
Log.e("jl", "帧动画已经播放到最后一帧");
return true;
}
} catch (Exception e) {
}
return false;
}
接下来记录属性动画,未完待续….