Android Animation--View animation

众所周知,Android中的动画发展以3.0为分界分为两个阶段。3.0 之前,android支持两种动画模式,tween animation, frame animation, 在android3.0中又引入了一个新的动画系统:property animation.可通过NineOldAndroids项目在3.0之前的系统中使用Property Animation.本篇将主要整理了一下view animation 的定义和使用。

Tween Animation

补间动画,给出两个关键帧,通过一些算法将给定属性值在给定的时间内在两个关键帧间渐变。这种动画只能应用于View对象,就是一系列View形状的变换,(主要有4种效果:缩放,平移,透明度渐变,旋转)动画的定义既可以用代码定义也可以用XML定义,当然,建议用XML定义。

两种方式的比较:

Java code XML 效果
AlphaAnimation alpha 渐变透明度动画效果
ScaleAnimation scale 渐变尺寸伸缩动画效果
TranslateAnimation translate 画面转换位置移动动画效果
RotateAnimation rotate 画面转移旋转动画效果

在xml中的定义方式

1.在res目录中新建anim文件夹

2.在anim目录中新建一个根标签为test_anim.xml(注意文件名小写)

    <?xml version="1.0" encoding="utf-8"?>  
    <set xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@[package:]anim/interpolator_resource"  
    android:shareInterpolator=["true" | "false"] >  
    <alpha  
    android:fromAlpha="float"  
    android:toAlpha="float" />  
    <scale  
    android:fromXScale="float"  
    android:toXScale="float"  
    android:fromYScale="float"  
    android:toYScale="float"  
    android:pivotX="float"  
    android:pivotY="float" />  
    <translate  
    android:fromXDelta="float"  
    android:toXDelta="float"  
    android:fromYDelta="float"  
    android:toYDelta="float" />  
    <rotate  
    android:fromDegrees="float"  
    android:toDegrees="float"  
    android:pivotX="float"  
    android:pivotY="float" />  
    <set>  
    ...  
    </set>  
</set>

例如:定义一个旋转动画 R.anim.rotate_anim

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<rotate
    android:duration="1500"
    android:fromDegrees="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="-1"
    android:repeatMode="restart"
    android:startOffset="-1"
    android:toDegrees="+360" />
</set>

注:布局文件必须有一个独立的根元素,可以是 ,, , , (持有一组其它的动画元素,甚至可以是内嵌的 set 元素) 中的一个

android:interpolator
应用于动画的插值器。该值必须是一个指定了插值器资源的引用(不是一个插值器的类名),在平台中有缺省的插值器资源可以使用,或者你可以创建自己的插值器资源,可以看下面关于插值器的讨论。
android:shareInterpolator
Boolean 值, true:代表在所有的子元素中共享同一个插值器

java代码中定义方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//在代码中定义 动画实例对象
private Animation myAnimation_Alpha;
private Animation myAnimation_Scale;
private Animation myAnimation_Translate;
private Animation myAnimation_Rotate;

//根据各自的构造方法来初始化一个实例对象
myAnimation_Alpha= new AlphaAnimation(0.1f, 1.0f);

myAnimation_Scale = new ScaleAnimation(0.0f, 1.5f, 0.0f, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

myAnimation_Translate= new TranslateAnimation(0.0f, -90.0f, 30.0f, 360.0f);

myAnimation_Rotate= new RotateAnimation(0.0f, 260.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f);

在代码中使用动画

1
2
3
4
5
6
ImageView image = (ImageView) findViewById(R.id.image); 
//加载使用xml定义的动画
Animation xmlAnim = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
image.startAnimation(xmlAnim);
//使用上面代码中定义的动画
image.startAnimation(myAnimation_Alpha);

XML定义方法中各个参数属性

Duration[long]: 属性为动画持续时间,时间以毫秒为单位
fillAfter [boolean]:当设置为true ,该动画转化在动画结束后被应用 加在标签
fillBefore[boolean]:当设置为true ,该动画转化在动画开始前被应用 加在标签
repeatCount[int]:动画的重复次数
RepeatMode[int]:定义重复的行为,1:重新开始 2:plays backward
startOffset[long]:动画之间的时间间隔,从上次动画停多少时间开始执行下个动画
zAdjustment[int]:定义动画的Z Order的改变,0:保持Z Order不变,1:保持在最上层,-1:保持在最下层

Frame Animation

帧动画,就像GIF图片,通过一系列Drawable依次显示来模拟动画的效果。在XML中的定义方式如下:
res/anim/frame_anim

1
2
3
4
5
6
7
8
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/drawable1" android:duration="200" />
<item android:drawable="@drawable/drawable2" android:duration="200" />
<item android:drawable="@drawable/drawable3" android:duration="200" />
<item android:drawable="@drawable/drawable4" android:duration="200" />
<item android:drawable="@drawable/drawable5" android:duration="200" />
</animation-list>

注:必须以为根元素,以表示要轮换显示的图片,duration属性表示各项显示的时间。XML文件放在/res/drawable/目录下。属性:android:oneshot :true:只执行一次动画,false:循环执行。

1
2
3
4
ImageView image = (ImageView) findViewById(R.id.image);  
image.setBackgroundResource(R.drawable_frame_anim);
frameAnim = (AnimationDrawable) image.getBackground();
frameAnim.start();

在实际使用时要注意:

  1. 要在代码中调用Imageview的setBackgroundResource方法,如果直接在XML布局文件中设置其src属性当触发动画时会FC。
  2. 在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次。
  3. 最后一点是SDK中提到的,不要在onCreate中调用start,因为AnimationDrawable还没有完全跟Window相关联,如果想要界面显示时就开始动画的话,可以在onWindowFoucsChanged()中调用start()。

Glide

Glide 被用来在ImageView 播放gif图,使用也非常简单。

下面演示在Android studio上使用Glide

  • 在app/build.gradle文件添加以下代码
1
2
3
4
dependencies {
...
compile 'com.github.bumptech.glide:glide:3.6.0'
}
  • 在布局文件中如:activity_main.xml中加上imageview布局

    1
    2
    3
    4
    5
    <ImageView
    android:id="@+id/ivGif"
    android:contentDescription="Gif"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
  • 加载本地的gif,确保gif资源放在res/raw下。MainActivity中的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
	public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find the ImageView to display the GIF
ImageView ivGif = (ImageView) findViewById(R.id.ivGif);
// Display the GIF (from raw resource) into the ImageView
Glide.with(this).load(R.raw.my_gif).asGif().into(imageView);
// OR even download from the network
//Glide.with(this).load("https://i.imgur.com/l9lffwf.gif").asGif().into(imageView);
}
}