1.什么是Animation?
2.Animation的分类?
3.Animation的使用?
Animation提供了一系列的动画效果,这些效果可以应用在绝大数的控件上。
Animation从总体来说可以分为两类:
Tweened Animations:该类提供了旋转,移动,伸展,淡入淡出等效果
Frame-By-Frame Animations:该类可以创建一个Drawable序列,这些Drawable可以按照指定的事件间隔一个一个显示,和动画片差不多。
Tweened Animations也有四种类型:
Alpha:淡入淡出效果
Scale:缩放效果
Rotate:旋转效果
Translate:移动效果
设置动画效果可以在XML文件中设置,也可以在Java代码中设置。
(1)Java代码中设置动画效果的步骤:
创建一个AnimationSet对象(AnimationSet是存放多个Animations的集合)
根据需要创建相应的Animation对象
根据需要对Animation对象的各个属性进行设值
将Animation对象添加到AnimationSet对象中
使用控件的startAnimation()方法执行AnimationSet
各种Animation的主要属性:
setDuration(long durationMillis):设置动画持续事件(单位:毫秒)
setFillAfter(boolean fillAfter):如果fillAfter设为true,则动画执行后,控件将停留在动画结束的状态
setFillBefore(boolean fillBefore):如果fillBefore设为true,则动画执行后,控件将回到动画开始的状态
setStartOffset(long startOffset):设置动画执行之前等待的时间(单位:毫秒)
setRepeatCount(int repeatCount):设置动画重复的次数
setInterpolator(Interpolator i):设置动画的变化速度
setInterpolator(new AccelerateDecelerateInterpolator()):先加速,后减速
setInterpolator(new AccelerateInterpolator()):加速
setInterpolator(new DecelerateInterpolator()):减速
setInterpolator(new CycleInterpolator()):动画循环播放特定次数,速率改变沿着正弦曲线
setInterpolator(new LinearInterpolator()):匀速
//第一种方法// // 创建一个AlphaAnimation对象// AlphaAnimation alphaAnimation = new AlphaAnimation(0.01f, 1f);// // 设置动画执行的时间(单位:毫秒)// alphaAnimation.setDuration(3000);// // 使用TextView的startAnimation()方法开始执行动画// textShow.startAnimation(alphaAnimation); //第二种方法 Animation animation = AnimationUtils.loadAnimation(this, R.anim.test_alpha); textShow.startAnimation(animation);下面是总体的代码:
package com.example.anjoyo_03_animation;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.AnimationSet;import android.view.animation.AnimationUtils;import android.view.animation.RotateAnimation;import android.view.animation.ScaleAnimation;import android.view.animation.TranslateAnimation;import android.widget.Button;import android.widget.TextView;public class MainActivity extends Activity implements OnClickListener { // btn1:scale 缩放 btn2:alpha 透明度 btn3:translate 位移 btn4:rotate 旋转 private Button btn1, btn2, btn3, btn4, btn5; private TextView textShow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textShow = (TextView) findViewById(R.id.text); btn1 = (Button) findViewById(R.id.btn_1); btn1.setOnClickListener(this); btn2 = (Button) findViewById(R.id.btn_2); btn2.setOnClickListener(this); btn3 = (Button) findViewById(R.id.btn_3); btn3.setOnClickListener(this); btn4 = (Button) findViewById(R.id.btn_4); btn4.setOnClickListener(this); btn5 = (Button) findViewById(R.id.btn_5); btn5.setOnClickListener(this); } /** * 常用参数的解读 * * Alpha:淡入淡出效果 * Scale:缩放效果 * Rotate:旋转效果 * Translate:移动效果 * * 0f 代表动画消失,即看不见 * 1f 代表动画完全显示 * 0.0f--1.0f动画的可见值一般在这之中取值 * * setDuration(毫秒) 动画的执行时间是多长 * setFillAfter() true:代表动画执行后,在执行后的位置 false:代表动画执行后,出现在原来的位置 * setFillBefore() false:代表动画执行后,在执行后的位置 true:代表动画执行后,出现在原来的位置 * setStartOffset() 动画之间的时间间隔,从上次动画停多少时间开始执行下个动画, 设置动画执行之前等待的时间(单位:毫秒) * * formXDelta 为动画起始时X坐标上的移动位置 * toXDelta 为动画结束时X坐标上的移动位置 * formYDelta 为动画起始时Y坐标上的移动位置 * toXDelta 为动画结束时Y坐标上的移动位置 * fromDegrees 开始旋转的角度 ,即从多少度开始旋转 * toDegrees 旋转的角度 ,即旋转多少度。当角度为负数——表示逆时针旋转 -- 当角度为正数——表示顺时针旋转 * Animation.RELATIVE_TO_SELF:相对于自身 Animation.RELATIVE_TO_PARENT:相对于父控件 * pivotXType X轴的位置类型 ,有 Animation.RELATIVE_TO_SELF和Animation.RELATIVE_TO_PARENT这两种 * fromXValue X轴的位置类型相对于控件的值 * pivotYType Y轴的位置类型 ,有 Animation.RELATIVE_TO_SELF和Animation.RELATIVE_TO_PARENT这两种 * fromXValue Y轴的位置类型相对于控件的值 */ @Override public void onClick(View v) { // 创建一个AnimationSet对象// AnimationSet animationSet = new AnimationSet(true); switch (v.getId()) { case R.id.btn_1: // 创建一个ScaleAnimation对象(以某个点为中心缩放) ScaleAnimation scaleAnimation = new ScaleAnimation( 0.1f, 1f, 0.1f, 1f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 1.0f); scaleAnimation.setDuration(3000); scaleAnimation.setStartOffset(10000); textShow.startAnimation(scaleAnimation); break; case R.id.btn_2: //第一种方法// // 创建一个AlphaAnimation对象// AlphaAnimation alphaAnimation = new AlphaAnimation(0.01f, 1f);// // 设置动画执行的时间(单位:毫秒)// alphaAnimation.setDuration(3000);// // 使用TextView的startAnimation()方法开始执行动画// textShow.startAnimation(alphaAnimation); //第二种方法 Animation animation = AnimationUtils.loadAnimation(this, R.anim.test_alpha); textShow.startAnimation(animation); break; case R.id.btn_3: //四个参数的构造方法// TranslateAnimation translateAnimation = new TranslateAnimation(50f, 100f, 0f, -100f);// translateAnimation.setDuration(2000);// //设置操作过后的动画是回到原来的位置还是在操作过后的位置//// translateAnimation.setFillAfter(true);// translateAnimation.setFillBefore(false); //跟上面的方法实现同样的效果// textShow.startAnimation(translateAnimation); //第一个参数 formXDelta为动画起始时X坐标上的移动位置 //第二个参数 toXDelta为动画结束时X坐标上的移动位置 //第三个参数 formYDelta为动画起始时Y坐标上的移动位置 //第四个参数 toXDelta为动画结束时Y坐标上的移动位置 TranslateAnimation translateAnimation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f); translateAnimation.setDuration(2000); textShow.startAnimation(translateAnimation); break; case R.id.btn_4: // 创建一个RotateAnimation对象(以某个点为圆心旋转360度) //相对于自己的360度旋转// RotateAnimation rotateAnimation = new RotateAnimation(0, 360, // Animation.RELATIVE_TO_SELF, 1f, // Animation.RELATIVE_TO_SELF, 2f); //相对于父控件的360度旋转 RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.3f); rotateAnimation.setDuration(2000); textShow.startAnimation(rotateAnimation); break; case R.id.btn_5: //第一种方法 // 创建一个AnimationSet对象 AnimationSet animationSet = new AnimationSet(false); ScaleAnimation scaleAnimation1 = new ScaleAnimation( 0.1f, 1f, 0.1f, 1f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 1.0f); RotateAnimation rotateAnimation1 = new RotateAnimation(0, 360, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.3f); animationSet.addAnimation(scaleAnimation1); animationSet.addAnimation(rotateAnimation1); animationSet.setDuration(2000); animationSet.setStartOffset(500); textShow.startAnimation(animationSet); // 第二种方法 // Animation animation = // AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha_rotate); // textShow.startAnimation(animation); break; } }}上面的Java代码设置动画效果有一个缺点:代码的可复用性很低,不利于维护。为了维护,可以使用XML来设置动画效果。
(2)XML中设置动画效果的步骤:
在res文件夹下新建一个名为anim的文件夹
创建xml文件,并首先加入set标签(set标签就相当于Java代码中的AnimationSet)
在Set标签中加入alpha,scale,rotate,translate标签(相当于Java代码中的AlphaAnimation,ScaleAnimation,RotateAnimation,TranslateAnimation)
在Java代码中使用AnimationUtils的loadAnimation方法来加载XML文件,并得到一个Animation对象
使用控件的startAnimation()方法执行这个Animation对象
AlphaAnimation很简单,不多说,直接看代码注释.
剩下的3中动画效果都涉及到了参考点的问题,下面我们逐一解释.
RotateAnimation的创建中用到了Animation.RELATIVE_TO_PARENT(表示以父控件为参考),另外还有2种参考:Animation.RELATIVE_TO_SELF(以自身为参考),Animation.ABSOLUTE(绝对坐标,没有参考).
我们就拿Animation.RELATIVE_TO_PARENT来画图讲解到底RotateAnimation旋转的圆心在哪儿?
例子中,X轴设置了相对于父控件,值是0.5f;Y轴设置了相对于父控件,值是0.25f。也就是说,圆心是0.5个父控件的width和0.25个父控件的height,
那么,控件就围绕着上图的圆心,从0°旋转到360°(如果是0,-360,那么就是0°旋转到-360°)
以父控件为参照理解了的话,以自身为参考就可以举一反三了。
ScaleAnimation的创建的参数的解释:缩放的中心点可以按照上文中的计算方法(如下图),缩小后的图片大小是0.1个自身width,0.1个自身height,相当于缩小90%.
TranslateAnimation的创建的参数的解释:参数主要是决定移动的起始点和终了点,计算方法参考上文.
1.AnimationSet的使用方法
2.AnimationSet实现动画的双重效果
3.Interpolator的使用方法
4.Frame-By-FrameAnimation的使用方法
AnimationSet(XML文件中是set标签),这个AnimationSet就相当于一个集合,可以存放一个或多个Animation对象,如果我们对AnimationSet设置属性值,那么,这些属性值将应用到AnimationSet下的所有Animation对象中去。
2.实现一个动画,既能够缩放又能够旋转,这时我们就要用到AnimationSet。
//第一种方法 // 创建一个AnimationSet对象 AnimationSet animationSet = new AnimationSet(false); ScaleAnimation scaleAnimation1 = new ScaleAnimation( 0.1f, 1f, 0.1f, 1f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 1.0f); RotateAnimation rotateAnimation1 = new RotateAnimation(0, 360, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.3f); animationSet.addAnimation(scaleAnimation1); animationSet.addAnimation(rotateAnimation1); animationSet.setDuration(2000); animationSet.setStartOffset(500); textShow.startAnimation(animationSet); // 第二种方法 // Animation animation = // AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha_rotate); // textShow.startAnimation(animation);对于第二种方法,我们在res文件夹下建一个anim的文件。然后
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" android:shareInterpolator="true" > <!-- interpolator 插入 器 accelerate 加速器 --> <alpha android:duration="2000" android:fromAlpha="1.0" android:startOffset="500" android:toAlpha="0.0" /> <rotate android:duration="2000" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="360" /></set>
interpolator定义一个动画的变化率(the rate of change)。这使得基本的动画效果(alpha, scale, translate, rotate)得以加速,减速,重复等。
Interpolator插入器.英文意思是: 篡改者; 分类机; 校对机
Interpolator借口只有一个抽象方法getInterpolation(float input),由此SDK中扩展了另外几个常用Interpolator类,分别是:
——AccelerateInterpolator:动画从开始到结束,变化率是一个加速的过程。
——DecelerateInterpolator:动画从开始到结束,变化率是一个减速的过程。
——CycleInterpolator:动画从开始到结束,变化率是循环给定次数的正弦曲线。
——AccelerateDecelerateInterpolator:动画从开始到结束,变化率是先加速后减速的过程。
——LinearInterpolator:动画从开始到结束,变化率是线性变化。
所有Interpolators 都实现Interpolator 接口(实际上为TimeInterpolator接口),这个接口定义了一个方法:
public abstract float getInterpolation(float input)
input 为正规化后动画的时间,值域总之0-1之间。 0代表开始时间,1代表结束时间。
返回值也是正规化后的值,可以代表平移的时间,旋转的角度,Alpha值变化,标准值域为0-1之间,但允许值小于0或大于1,表示插值到标准区域两边。
总的来说,Interpolator定义了动画变化的速率,提供提供不同的函数定义变化值相对于时间的变化规则,可以定义各种各样的非线性变换函数,比如加速,减速等。
Android 系统自带了多种Interpolator 可以通过多种动画变化效果:
AccelerateDecelerateInterpolator 先加速再减速
AccelerateInterpolator 加速
AnticipateInterpolator 先回退一小步,然后再迅速前进
AnticipateOvershootInterpolator 先回退一小步,然后再迅速前进,在超过右边界一小步
BounceInterpolator 实现弹球效果
CycleInterpolator 周期运动
DecelerateInterpolator 减速
LinearInterpolator 匀速
OvershootInterpolator 快速前进到右边界上,再往外突出一小步
这些Interpolator 可以应用于任意的Animation中,如TranslateAnimation, RotateAnimation, ScaleAnimation ,AlphaAnimation 等,其插值的对象随Animation 种类不同而不同。比如对于TranslateAnimation来说,插值的对象是位移,对应的动画是平移的速率。对于RotateAnimation来说插值的对象为旋转角度,对应的动画为旋转的速率。
Frame Animation
Frame Animation是顺序播放事先做好的图像,跟电影类似。不同于animation package,Android SDK提供了另外一个类AnimationDrawable来定义、使用Frame Animation。
Frame Animation可以在XML Resource定义(还是存放到res\anim文件夹下),也可以使用AnimationDrawable中的API定义。由于Tween Animation与Frame Animation有着很大的不同,因此XML定义的格式也完全不一样,其格式是:首先是animation-list根节点,animation-list根节点中包含多个item子节点,每个item节点定义一帧动画,当前帧的drawable资源和当前帧持续的时间。下面对节点的元素加以说明:
XML属性 说明
drawable 当前帧引用的drawable资源
duration 当前帧显示的时间(毫秒为单位)
oneshot 如果为true,表示动画只播放一次停止在最后一帧上,如果设置为false表示动画循环播放。
variablePadding If true, allows the drawable’s padding to change based on the current state that is selected.
visible 规定drawable的初始可见性,默认为flase;
AnimationDrawable(获取、设置动画的属性)
int getDuration() 获取动画的时长
int getNumberOfFrames() 获取动画的帧数
boolean isOneShot() 获取oneshot属性
Void setOneShot(boolean oneshot) 设置oneshot属性
void inflate(Resurce r,XmlPullParser p,AttributeSet attrs) 增加、获取帧动画
Drawable getFrame(int index) 获取某帧的Drawable资源
void addFrame(Drawable frame,int duration) 为当前动画增加帧(资源,持续时长)
动画控制
void start() 开始动画
void run() 外界不能直接掉调用,使用start()替代
boolean isRunning() 当前动画是否在运行
void stop() 停止当前动画
有一点需要强调的是:启动Frame Animation动画的代码animationDrawable.start();不能在OnCreate()中,因为在OnCreate()中AnimationDrawable还没有完全的与ImageView绑定,在OnCreate()中启动动画,就只能看到第一张图片。这里实在拖曳事件中实现的。
package com.example.mars_02_10_animation05;import android.os.Bundle;import android.app.Activity;import android.graphics.drawable.AnimationDrawable;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;public class MainActivity extends Activity { private Button button; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = (ImageView) findViewById(R.id.imageViewId); button = (Button) findViewById(R.id.scaleButtonId); button.setOnClickListener(new AnimationButtonListener()); } class AnimationButtonListener implements OnClickListener { @Override public void onClick(View v) { imageView.setBackgroundResource(R.drawable.anim_list); AnimationDrawable animationDrawable = (AnimationDrawable)imageView.getBackground(); animationDrawable.start(); } }}
<?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/nv1" android:duration="500" /> <item android:drawable="@drawable/nv2" android:duration="500" /> <item android:drawable="@drawable/nv3" android:duration="500" /> <item android:drawable="@drawable/nv4" android:duration="500" /></animation-list>
2.ListView与Animations的结合使用
3.AnimationListener的使用方法
<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" > <ListView android:id="@id/android:list" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layoutAnimation="@anim/list_anim_layout" android:scrollbars="vertical" /> <Button android:id="@+id/buttonId" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="测试" /></LinearLayout>
package com.example.mars_02_11_animations06;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import android.app.ListActivity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.view.animation.LayoutAnimationController;import android.widget.Button;import android.widget.ListAdapter;import android.widget.ListView;import android.widget.SimpleAdapter;public class MainActivity extends ListActivity { private Button button; private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.buttonId); listView = getListView(); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listView.setAdapter(buildListAdapter()); Animation animation = AnimationUtils.loadAnimation( MainActivity.this, R.anim.list_anim); LayoutAnimationController lac = new LayoutAnimationController( animation); lac.setOrder(LayoutAnimationController.ORDER_NORMAL); lac.setDelay(0.5f); listView.setLayoutAnimation(lac); } }); } private ListAdapter buildListAdapter() { List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(); HashMap<String, String> map1 = new HashMap<String, String>(); map1.put("user_name", "zhangsan"); map1.put("user_gender", "female"); HashMap<String, String> map2 = new HashMap<String, String>(); map2.put("user_name", "lisi"); map2.put("user_gender", "male"); HashMap<String, String> map3 = new HashMap<String, String>(); map3.put("user_name", "wangwu"); map3.put("user_gender", "female"); list.add(map1); list.add(map2); list.add(map3); SimpleAdapter simpleAdapter = new SimpleAdapter(MainActivity.this, list, R.layout.item, new String[] { "user_name", "user_gender" }, new int[] { R.id.user_name, R.id.ueser_gender }); return simpleAdapter; }}
什么是LayoutAnimationController呢?LayoutAnimationController用于为一个Layout里面的一组控件设置相同的动画效果,并可以控制这一组动画在不同的时间出现
LayoutAnimationController可以在XML中设置,也可在Java代码中设置
layoutAnimation标签中的android:animationOrder属性就是设置动画的显示顺序的,normal就是依次显示出来
如果要在Java代码中设置LayoutAnimation,可以按照如下设置
删掉list_anim_layout.xml文件,删掉main.xml下的ListView的android:layoutAnimation属性,最后,在OnClick方法里面加上如下代码:
Animation animation = (Animation) AnimationUtils.loadAnimation(this, R.anim.list_anim);
LayoutAnimationController lac = new LayoutAnimationController(animation);
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
lac.setDelay(0.5f);
mListView.setLayoutAnimation(lac);
package com.example.mars_02_11_animations07;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.ViewGroup.LayoutParams;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.widget.Button;import android.widget.ImageView;public class MainActivity extends Activity { private Button removebutton; private Button addButton; private ImageView imageView; private ViewGroup viewGroup; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); removebutton = (Button) findViewById(R.id.removeButtonId); addButton = (Button) findViewById(R.id.addButtonId); viewGroup = (ViewGroup) findViewById(R.id.layoutId); imageView = (ImageView) findViewById(R.id.imageViewId); addButton.setOnClickListener(new AddButtonListener()); removebutton.setOnClickListener(new RemovebuttonListener()); } class AddButtonListener implements OnClickListener{ @Override public void onClick(View v) { //创建一个淡入效果的Animation对象 AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f); animation.setDuration(1000); animation.setStartOffset(500); //创建一个新的ImageView ImageView imageViewAdd = new ImageView(MainActivity.this); imageViewAdd.setImageResource(R.drawable.img1); //将新的ImageView添加到ViewGroup当中 viewGroup.addView(imageViewAdd,new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); //启动动画 imageViewAdd.startAnimation(animation); } } class RemovebuttonListener implements OnClickListener { @Override public void onClick(View v) { //创建一个淡出效果的Animation对象 AlphaAnimation animation = new AlphaAnimation(1.0f, 0.0f); //为Animation对象设置属性 animation.setDuration(1000); animation.setStartOffset(300); //为Animation对象设置监听器 animation.setAnimationListener(new RemoveAnimationlistener()); imageView.startAnimation(animation); } } class RemoveAnimationlistener implements AnimationListener { @Override public void onAnimationStart(Animation animation) { System.out.println("--->start"); } //该方法在淡出效果执行结束之后被调用 @Override public void onAnimationEnd(Animation animation) { System.out.println("--->end"); //从viewGroup当中删除掉image控件 viewGroup.removeView(imageView); } @Override public void onAnimationRepeat(Animation animation) { System.out.println("--->repeat"); } }}
代码已经打包:http://download.csdn.net/detail/u012301841/7660877