最近自学了安卓的animations,考虑到以后复习方便,现写篇博客以方便自己以后查阅。(以下大多数据是测试所得,难免会有错误的地方,请发现的朋友在下面回复告诉我,让我改正,谢谢!)
一、Frame-By-Frame Animations(逐帧动画)
逐帧动画就是顺序播放事先准备好的静态图像,利用人眼的”视觉残留“原理,给用户造成动画的错觉。实现逐帧动画很简单,现以通过ImageView控件更换背景来实现动画的效果
(1)先准备5张连续的动作图片,分别名为pic1.jpg、pic2.jpg、pic3.jpg、pic4.jpg,放到drawable-hdpi文件夹下
(2)在res/drawable当中创建一个名为anim_nv.xml的xml文件,用于定义animations的动画序列,代码如下:
1 <?xml version="1.0" encoding="utf-8"?>
2
3 <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
4
5 android:oneshot="false">
6
7 <item android:drawable="@drawable/pic1" android:duration="500"></item>
8
9 <item android:drawable="@drawable/pic2" android:duration="500"></item>
10
11 <item android:drawable="@drawable/pic3" android:duration="500"></item>
12
13 <item android:drawable="@drawable/pic4" android:duration="500"></item>
14
15 </animation-list>
上面的代码中,android:oneshot属性用于设置是否循环播放,默认值为true,表示循环播放;android:drawable属性用于指定要显示的图片资源;android:duration属性用于指定图片资源持续的时间。
(3)在布局文件activity_main.xml中写两个控件,代码如下:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent">
5 <Button
6 android:id="@+id/buttonId"
7 android:layout_width="wrap_content"
8 android:layout_height="wrap_content"
9 android:layout_alignParentBottom="true"
10 android:text="点我播放动画">
11 </Button>
12 <LinearLayout
13 android:orientation="vertical"
14 android:layout_width="match_parent"
15 android:layout_height="match_parent">
16 <ImageView
17 android:id="imageViewId"
18 android:layout_width="wrap_content"
19 android:layout_height="wrap_content"
20 android:layout_gravity="center"
21 android:layout_marginTop="100dp">
22 </ImageView>
23 </LinearLayout>
24 </RelativeLayout>
(4)在MainActivity.java中如下代码:
1 package com.android.frame_by_frame;
2
3 import android.app.Activity;
4 import android.graphics.drawable.AnimationDrawable;
5 import android.os.Bundle;
6 import android.view.View;
7 import android.view.View.OnClickListener;
8 import android.widget.Button;
9 import android.widget.ImageView;
10
11 public class MainActivity extends Activity {
12
13 private Button button;
14 private ImageView imageView;
15 @Override
16 protected void onCreate(Bundle savedInstanceState) {
17 super.onCreate(savedInstanceState);
18 setContentView(R.layout.activity_main);
19 imageView = (ImageView)this.findViewById(R.id.imageViewId);
20 button = (Button)this.findViewById(R.id.buttonId);
21 button.setOnClickListener(new OnClickListener() {
22 @Override
23 public void onClick(View v) {
24 imageView.setBackgroundResource(R.drawable.aim_nv);
25 AnimationDrawable ad = (AnimationDrawable)imageView.getBackground();
26 ad.start();
27 }
28 });
29 }
30
31 }
这样,就达到了点击按钮,那4张图片就按顺序像幻灯片一样播放了,步骤比较简单,这里就不做过多介绍了。
二、Tweened Animations(渐变动画)
分为4类,实现方法也是有两种:
第一种方法:在代码中使用的方法,使用步骤大致如下:
a.创建一个AnimationSet对象
b.根据需要创建相应的Animation对象
c.根据软件动画的需求,为Animation对象设置相应的数据
d.讲Animation对象添加到AnimationSet对象中
e.使用控件对象开始执行AnimationSet
1.Alpha Animation(通明度变化动画)
关键代码片段(也是以ImageView为例):
1 AnimationSet animationSet = new AnimationSet(true); //这里参数为true的作用会在下面讲到
2 AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
3 alphaAnimation.setDuration(2000);
4 animationSet.addAnimation(alphaAnimation);
5 imageView.startAnimation(animationSet);
AlphaAnimation的构造函数参数说明:
param1 float fromAlpha --------------开始时的不透明度
param2 float toAlpha -----------------结束时的不透明度
Tween Animation通用的属性:
<1>setDuration(long durationMills) 设置动画持续时间(单位:毫秒)
<2>setFillAfter(boolean fillAfter) 如果fillAfter的值为rue,则动画执行后,控件将停留在执行结束时的状态
<3>setFillBefore(boolean fillBefore) 如果fillBefore的值为rue,则动画执行后,控件将回到在执行前的状态
<4>setStartOffset(long startOffset) 设置动画执行之前的等待时间(单位:毫秒)
<5>setRepeatCount(int repeatCount) 设置动画重复的次数
2.Rotate Animation(旋转动画)
关键代码片段(也是以ImageView为例):
1 AnimationSet animationSet = new AnimationSet(true);
2 RotateAnimation rotateAnimation = new RotateAnimation(
3 0,360,
4 Animation.RELATIVE_TO_PARENT,1f,
5 Animation.RELATIVE_TO_PARENT,0.5f
6 );
7 rotateAnimation.setDuration(2000);
8 animationSet.addAnimation(rotateAnimation);
9 imageView.startAnimation(animationSet);
RotateAnimation构造函数参数说明:
param 1 float fromDegree--------------选择开始时的角度(从控件原本位置与轴心的连线为0度并且顺时针旋转计算)
param 2 float toDegree--------------旋转停止时的角度
param 3 int pivotXType--------------选择轴心x轴的类型:供选择的类型有三种(具体用法下面再讲)
Animation.ABSOLUTE-----------------相对于手机频幕
Animation.RELATIVE_TO_SELF------------相对于自身控件
Animation.RELATIVE_TO_PARENT---------相对于父控件
param 4 float pivotXValue----------------轴心X轴的值
param 5 int pivotYType--------------选择轴心Y轴的类型(和pivotXType的供选择的类型一样)
param 6 float pivotYvalue-------------轴心Y轴的值
这里来讲轴心的三种确定类型
Animation.ABSOLUTE(相对于手机频幕):以手机频幕左上角为原点,向右为X轴正方向,向下为Y轴正方向
Animation.RELATIVE_TO_SELF(相对于自身控件):以自身控件左上角为原点,向右为X轴正方向,向下为Y轴正方向
Animation.RELATIVE_TO_PARENT(相对于父控件):以父控件左上角为原点,向右为X轴正方向,向下为Y轴正方向
3.Scale Animation(伸缩动画)
关键代码片段(也是以ImageView为例):
1 AnimationSet animationSet = new AnimationSet(true);
2 ScaleAnimation scaleAnimation = new ScaleAnimation(
3 1.0f, 0.0f,
4 1.0f,0.1f,
5 Animation.RELATIVE_TO_SELF,0.5f,
6 Animation.RELATIVE_TO_SELF,0.5f
7 );
8 scaleAnimation.setDuration(2000);
9 animationSet.addAnimation(scaleAnimation);
10 imageView.startAnimation(animationSet);
ScaleAnimation构造函数参数说明:
param1 float fromX ------------伸缩开始时在x轴(以自身控件的左上角为原点,向右为x轴正,向下为y轴正)上的伸缩尺寸(大于1表示放大,小于1表示缩小,等于1表示不便,等于0表示缩放到没有)
param2 float toX ------------伸缩结束时在x轴上的伸缩尺寸
param3 float fromY ----------伸缩开始时在y轴上的伸缩尺寸
param4 float toY ------------伸缩结束时在y轴上的伸缩尺寸
param5 int pivotXType -----------在x轴上确定伸缩轴心所用的类型
param6 float pivotXValue ------------在x轴上确定伸缩轴心的值
param7 int pivotYType ------------在y轴上确定伸缩轴心所用的类型
param8 float pivotYValue ------------在y轴上确定伸缩轴心的值
4.Translate Animation(平移动画)
关键代码片段(也是以ImageView为例):
1 AnimationSet animationSet = new AnimationSet(true);
2 TranslateAnimation translateAnimation = new TranslateAnimation(
3 Animation.RELATIVE_TO_SELF,0.0f,
4 Animation.RELATIVE_TO_SELF,0.5f,
5 Animation.RELATIVE_TO_SELF,0.0f,
6 Animation.RELATIVE_TO_SELF,1.0f
7 );
8 translateAnimation.setDuration(2000);
9 animationSet.addAnimation(translateAnimation);
10 imageView.startAnimation(animationSet);
TranslateAnimation构造函数参数说明:
param1 int fromXType ----------平移开始时在x轴(正方向位置和上面的一样)上的平移类型
param2 float fromXValue -----------平移开始时在x轴上的平移值
param3 int toXType ------------平移结束时在x轴上的平移类型
param4 float toXValue ---------平移结束时在x轴上的平移值
param5 int fromYType ---------平移开始时在y轴上的平移类型
param6 float fromYValue---------平移开始时在y轴上的平移值
param7 int toYType-----------平移结束时在y轴上的平移类型
param8 float toYValue----------平移结束时在y轴上的平移值
第二种方法:在xml文件中使用的方法,使用步骤大致如下:
a.在res文件夹下创建一个名为anim的文件夹
b.创建xml文件,并首先加入set,改标签如下:
1 <Set xmlns:android="http://schemas.android.com/apk/res/android"
2 android:interpolator="@android:anim/accelerate_interpolator">
3 </Set>
android:interpolator属性是用于控制动画变化的速率,常用的有以下几种属性值(其他的见官方api文档):
AccelerateDecelerateInterpolator:在动画开始和结束的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator:在动画开始的地方速率比较慢,然后开始加速速
CycleInterpolator:动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator:在动画开始的地方快然后慢
LinearInterpolater:使动画以均匀的速率改变
c.在该标签当中加入有需求的动画对应的标签
d.在代码当中使用AnimationUtils当中装载xml文件,并生成Animation对象
e.使用空间对象的startAnimation()开始执行动画
ps:上面出现的set标签的作用会在下面的内容详细讲到
1.Alpha Animation
在xml文件(alpha.xml)中的代码:
1 <Set xmlns:android="http://schemas.android.com/apk/res/android"
2 android:interpolator="@android:anim/accelerate_interpolator">
3 <Alpha
4 android:fromAlpha="0.1"
5 android:toAlpha="1.0"
6 android:duration="3000"/>
7 </Set>
在activity(MainActivity.java)里的代码:
1 Animation alphaAnimation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha);
2 imageView.startAnimation(alphaAnimation);
2.Rotate Animation
在xml文件(rotate.xml)中的代码:
1 <Set xmlns:android="http://schemas.android.com/apk/res/android"
2 android:interpolator="@android:anim/accelerate_interpolator">
3 <Rotate
4 android:fromDegrees="0"
5 android:toDegrees="+360"
6 android:pivotX="50%"
7 android:pivotY="50%"
8 android:duration="1000"/>
9 </Set>
android:pivotX(pivotY也一样)的值有三种设置方法:
android:pivotX="50" 这种写法使用绝对位置定位,相当于前面介绍的Animation.ABSOLUTE
android:pivotX="50%" 这种写法相对于控件自身定位,相当于前面介绍的Animation.RELATIVE_TO_SELF
android:pivotX="50%p" 这种写法相对于控件的父控件定位,相当于前面介绍的Animation.RELATIVE_TO_PARENT
在activity(MainActivity.java)里的代码:
1 Animation rotateAnimation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.rotate);
2 imageView.startAnimation(RotateAnimation);
3.Translate Animation
在xml文件(translate.xml)中的代码:
1 <Set xmlns:android="http://schemas.android.com/apk/res/android"
2 android:interpolator="@android:anim/accelerate_interpolator">
3 <Translate
4 android:fromXDelta="0"
5 android:toXDelta="+360" //+表示顺时针方向 -逆时针
6 android:fromYDelta="50%"
7 android:toYDelta="50%"
8 android:duration="2000"/>
9 </Set>
在activity(MainActivity.java)里的代码:
1 Animation translateAnimation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.translate);
2 imageView.startAnimation(translateAnimation);
4.Scale Animation
在xml文件(scale.xml)中的代码:
1 <Set xmlns:android="http://schemas.android.com/apk/res/android"
2 android:interpolator="@android:anim/accelerate_interpolator">
3 <Scale
4 android:fromXScale="0"
5 android:toXScale="0"
6 android:fromYScale="1.0"
7 android:toYScale="0"
8 android:pivotX="50%"
9 android:pivotY="50%"
10 android:duration="2000"/>
11 </Set>
在activity(MainActivity.java)里的代码:
1 Animation scaleAnimation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.scale);
2 imageView.startAnimation(scaleAnimation);
三、AnimationSet
AnimationSet是Animation的子类,一个AnimationSet可以包含一系列的Animation,可以针对AnimationSet设置一些animation常用的属性(如:startOffset、duration等等),这些属性值就可以应用到AnimationSet里的所用animation
比如我现在使用动画做一个点击按钮后,图片在旋转的同时又淡出的效果,就可以这么实现:
第一种方法:
布局文件中有两个控件:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent">
5 <Button
6 android:id="@+id/buttonId"
7 android:layout_width="match_parent"
8 android:layout_height="wrap_content"
9 android:layout_alignParentBottom="true"
10 android:text="点我看效果">
11 </Button>
12 <LinearLayout
13 android:layout_width="match_parent"
14 android:layout_height="match_parent">
15 <ImageView
16 android:id="@+id/imageViewId"
17 android:layout_width="wrap_content"
18 android:layout_height="wrap_content"
19 android:src="@drawable/ic_launcher"
20 android:layout_gravity="center">
21 </ImageView>
22 </LinearLayout>
23 </RelativeLayout> -->
activity里:
1 package com.android.animationset;
2
3 import android.os.Bundle;
4 import android.app.Activity;
5 import android.view.Menu;
6 import android.view.View;
7 import android.view.View.OnClickListener;
8 import android.view.animation.AlphaAnimation;
9 import android.view.animation.Animation;
10 import android.view.animation.AnimationSet;
11 import android.view.animation.RotateAnimation;
12 import android.widget.Button;
13 import android.widget.ImageView;
14
15 public class MainActivity extends Activity {
16
17 private Button button;
18 private ImageView imageView;
19 @Override
20 protected void onCreate(Bundle savedInstanceState) {
21 super.onCreate(savedInstanceState);
22 setContentView(R.layout.activity_main);
23 imageView = (ImageView)this.findViewById(R.id.imageViewId);
24 button = (Button)this.findViewById(R.id.buttonId);
25 button.setOnClickListener(new ButtonListener());
26
27 }
28
29 class ButtonListener implements OnClickListener{
30 @Override
31 public void onClick(View view) {
32 AnimationSet animationSet = new AnimationSet(true);
33 animationSet.setInterpolator(new DecelerateInterpolator());
34 AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
35 RotateAnimation rotateAnimation = new RotateAnimation(0,360,
36 Animation.RELATIVE_TO_SELF,0.5f,
37 Animation.RELATIVE_TO_SELF,0.5f);
38 animationSet.addAnimation(alphaAnimation);
39 animationSet.addAnimation(rotateAnimation);
40 animationSet.setDuration(1000);
41 animationSet.setStartOffset(500);
42 imageView.startAnimation(animationSet);
43 }
44
45 }
46 }
第二种方法:
在res文件夹下新建一个anim文件夹,在里面编写一个名为animations.xml的xml文件,其中代码如下:
1 <?xml version="1.0" encoding="utf-8"?>
2 <set xmlns:android="http://schemas.android.com/apk/res/android"
3 android:interpolator="@android:anim/accelerate_interpolator"
4 android:shareInterpolator="true">
5 <alpha
6 android:fromAlpha="1.0"
7 android:toAlpha="0.0"
8 android:startOffset="500"
9 android:duration="1000">
10 </alpha>
11 <rotate
12 android:fromDegrees="0"
13 android:toDegrees="360"
14 android:pivotX="50%"
15 android:pivotY="50%"
16 android:startOffset="500"
17 android:duration="1000">
18 </rotate>
19 </set>
在activity里写代码片段如下:
1 Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.animations);
2 imageView.startAnimation(animation);
ps:上面代码中的android:shareInterpolator就是控制set标签里的所有动画是否都按照android:interpolator的速率,而在以上的AnimationSet(true)就是相当于在set标签中把shareinterpolator值设置为true