动画详解
定义:
Animations是一个实现android UI界面动画效果的API,Animations提供了一系列的动画效果,
可以进行旋转、缩放、淡入淡出、位移等,这些效果可以应用在绝大多数的控件中。
实现原理:
每次绘制View时,ViewGroup中的drawChild函数获取该view的Animation的Transformation值,
然后调用canvas.concat(transformToApply.getMatrix())
通过矩阵运算完成帧动画,如果动画没有完成,就继续调用invalidate() 函数,启动下次绘制来驱动动画,从而完成整个动画的绘制。
当一个 ChildView 要重画时,它会调用其成员函数 invalidate() 函数将通知其 ParentView 这个 ChildView 要重画,
这个过程一直向上遍历到 ViewRoot,当 ViewRoot 收到这个通知后就会调用上面提到的 ViewRoot 中的 draw 函数从而完成绘制。
Android 动画就是通过 ParentView 来不断调整 ChildView 的画布坐标系来实现的。
分类机制:
XML动画
优点:
在xml文件中配置Animations,这样做可维护性变高了,只不过不容易进行调试。
步骤:
1.在res文件夹下建立一个anim文件夹;
2.创建xml文件,并首先加入set标签,更改标签如下:
3.在该标签当中加入rotate,alpha,scale或者translate标签;
4.在代码当中使用AnimationUtils当中装载xml文件,并生成Animation对象。
因为Animation是AnimationSet的子类,所以向上转型,用Animation对象接收。
Animation animation = AnimationUtils.loadAnimation( Animation1Activity.this, R.anim.alpha);
image.startAnimation(animation);
Java代码:
帧动画:
定义:
这一类Animations可以创建一个Drawable序列,这些Drawable可以按照指定的时间间歇一个一个的显示。
工作原理:
就是将一个完整的动画拆分成一张张单独的图片,然后再将它们连贯起来进行播放,类似于动画片的工作原理。
使用:
imageView.setBackgroundResource(R.anim.anim);
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getBackground();
animationDrawable.start();
补间动画:
定义:
补间动画,只是一个动画效果,组件其实还在原来的位置上,xy没有改变,改变的是内容的位置。(显示效果)
因此,他的缺点是,不具备交互性,无法响应点击事件。
通用方法:
1、setDuration(long durationMills)
设置动画持续时间(单位:毫秒)
2、setFillAfter(Boolean fillAfter)
如果fillAfter的值为true,则动画执行后,控件将停留在执行结束的状态
3、setFillBefore(Boolean fillBefore)
如果fillBefore的值为true,则动画执行后,控件将回到动画执行之前的状态
4、setStartOffSet(long startOffSet)
设置动画执行之前的等待时间
5、setRepeatCount(int repeatCount)
设置动画重复执行的次数
分类:
AlphaAnimation
//创建一个AnimationSet对象,参数为Boolean型,
//true表示使用Animation的interpolator,false则是使用自己的
AnimationSet animationSet = new AnimationSet(true);
//创建一个AlphaAnimation对象,参数从完全的透明度,到完全的不透明
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
//设置动画执行的时间
alphaAnimation.setDuration(500);
//将alphaAnimation对象添加到AnimationSet当中
animationSet.addAnimation(alphaAnimation);
//使用ImageView的startAnimation方法执行动画
image.startAnimation(animationSet);
TranslateAnimation
AnimationSet animationSet = new AnimationSet(true);
//参数1~2:x轴的开始位置
//参数3~4:y轴的开始位置
//参数5~6:x轴的结束位置
//参数7~8:x轴的结束位置
TranslateAnimation translateAnimation =
new TranslateAnimation(
Animation.RELATIVE_TO_SELF,0f,
Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0f,
Animation.RELATIVE_TO_SELF,0.5f);
translateAnimation.setDuration(1000);
animationSet.addAnimation(translateAnimation);
image.startAnimation(animationSet);
ScaleAnimation
AnimationSet animationSet = new AnimationSet(true);
//参数1:x轴的初始值
//参数2:x轴收缩后的值
//参数3:y轴的初始值
//参数4:y轴收缩后的值
//参数5:确定x轴坐标的类型
//参数6:x轴的值,0.5f表明是以自身这个控件的一半长度为x轴
//参数7:确定y轴坐标的类型
//参数8:y轴的值,0.5f表明是以自身这个控件的一半长度为x轴
ScaleAnimation scaleAnimation = new ScaleAnimation(
0, 0.1f,0,0.1f,
Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0.5f);
scaleAnimation.setDuration(1000);
animationSet.addAnimation(scaleAnimation);
image.startAnimation(animationSet);
RotateAnimation
AnimationSet animationSet = new AnimationSet(true);
//参数1:从哪个旋转角度开始
//参数2:转到什么角度
//后4个参数用于设置围绕着旋转的圆的圆心在哪里
//参数3:确定x轴坐标的类型,有ABSOLUT绝对坐标、RELATIVE_TO_SELF相对于自身坐标、RELATIVE_TO_PARENT相对于父控件的坐标
//参数4:x轴的值,0.5f表明是以自身这个控件的一半长度为x轴
//参数5:确定y轴坐标的类型
//参数6:y轴的值,0.5f表明是以自身这个控件的一半长度为x轴
RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(1000);
animationSet.addAnimation(rotateAnimation);
image.startAnimation(animationSet);
缺陷:
不能对非View对象进行动画操作;
不能对View的背景色进行改变;
只改变View的显示效果,并未改变其真实属性;
属性动画:
定义:
是一种不断地对值进行操作的机制,并将值赋值到指定对象的指定属性上,可以是任意对象的任意属性。
ValueAnimator(对值进行操作)最核心的一个类
原理:
它的内部使用一种时间循环的机制,来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,
并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。
方法:
ValueAnimator当中最常用的应该就是ofFloat( )和ofInt( )这两个方法了,另外还有一个ofObject()方法;
调用setStartDelay()方法来设置动画延迟播放的时间,调用setRepeatCount( )和setRepeatMode( )方法,
来设置动画循环播放的次数以及循环播放的模式,
循环模式包括RESTART和REVERSE两种,分别表示重新播放和倒序播放的意思;
ObjectAnimator(对任意对象)继承自ValueAnimator
定义:
它是可以直接对任意对象的任意属性进行动画操作的,比如说View的alpha属性。
ObjectAnimator在设计的时候就没有针对于View来进行设计,而是针对于任意对象的,
它所负责的工作就是不断地向某个对象中的某个属性进行赋值,然后对象根据属性值的改变再来决定如何展现出来。
ObjectAnimator内部的工作机制是通过寻找特定属性的get和set方法,然后通过方法不断地对值进行改变,从而实现动画效果的
ObjectAnimator内部的工作机制,并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法,
因此alpha属性所对应的get和set方法应该就是:
-
- public void setAlpha(float value);
- public float getAlpha();
方法:
offFloat();
可使用alpha、rotation、translationX和scaleY这几个值,分别完成淡入淡出、旋转、水平移动、垂直缩放这几种动画。
ObjectAnimator内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法。
关系:
相比于ValueAnimator,ObjectAnimator可能才是我们最常接触到的类,因为ValueAnimator只不过是对值进行了一个平滑的动画过渡,
但我们实际使用到这种功能的场景好像并不多。
而ObjectAnimator则就不同了,它是可以直接对任意对象的任意属性进行动画操作的,比如说View的alpha属性。
不过虽说ObjectAnimator会更加常用一些,但是它其实是继承自ValueAnimator的,底层的动画实现机制也是 基于ValueAnimator来完成的,
因此ValueAnimator仍然是整个属性动画当中最核心的一个类。
那么既然是继承关系,说明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的,它们的用法也非常类似。
组合动画:
定义:
实现组合动画功能主要需要借助AnimatorSet这个类,这个类提供了一个play()方法,
我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,
AnimatorSet.Builder中包括以下四个方法:
* after(Animator anim) 将现有动画插入到传入的动画之后执行
* after(long delay) 将现有动画延迟指定毫秒后执行
* before(Animator anim) 将现有动画插入到传入的动画之前执行
* with(Animator anim) 将现有动画和传入的动画同时执行
实例:
1. ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
2. ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
3. ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
4. AnimatorSet animSet = new AnimatorSet();
5. animSet.play(rotate).with(fadeInOut).after(moveIn);
6. animSet.setDuration(5000);
7. animSet.start();
动画集(AnimationSet)
定义:
1.AnimationSet是Animation的子类;
2.一个AnimationSet包含了一系列的Animation;
3.针对AnimationSet设置一些Animation的常见属性(如startOffset,duration等),可以被包含在AnimationSet当中的Animation集成;
使用:
AnimationSet animationSet = new AnimationSet(true);
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(1000);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(alphaAnimation);
image.startAnimation(animationSet);
LayoutAnimationsController
作用:
可实现多个控件按顺序一个一个的显示;
1)、LayoutAnimationsController用于为一个layout里面的控件,或者是一个ViewGroup里面的控件设置统一的动画效果。
2)、每一个控件都有相同的动画效果。
3)、控件的动画效果可以在不同的时间显示出来。
4)、LayoutAnimationsController可以在xml文件当中设置,以可以在代码当中进行设置。
实现:(XML)
1、
先在res下新建anim文件夹,新建一个文件alpha.xml
-
- <?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"
- >
- <alpha
- android:fromAlpha="0"
- android:toAlpha="1"
- android:duration="3000"
- />
- </set>
2、然后新建一个文件layoutanimation.xml
-
- <?xml version="1.0" encoding="utf-8"?>
- <layoutAnimation
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:delay="0.5"
- android:animationOrder="normal"
- android:animation="@anim/alpha"
- />
3、
在listview中使用下面代码
<ListView
android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layoutAnimation="@anim/layoutanimation”/>
代码实现:
AlphaAnimation alpha=
new
AlphaAnimation(
0
,
1
);
alpha.setDuration(
3000
);
LayoutAnimationController lac=
new
LayoutAnimationController(alpha);
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
lv.setLayoutAnimation(lac);
辅助类
动画插值器(Interpolator)
定义:
定义了动画变化的速率;
分类:
AccelerateDecelerateInterpolator:在动画开始与结束的地方速率改变比较慢,在中间的时候速率快。(先慢中快后慢)
AccelerateInterpolator:在动画开始的地方速率改变比较慢,然后开始加速。 (先慢后快)
DecelerateInterpolator:在动画开始的地方速率改变比较快,然后开始减速。 (先快后慢)
CycleInterpolator:动画循环播放特定的次数,速率改变沿着正弦曲线。 (循环播放,速度为正炫曲线)
LinearInterpolator:动画以均匀的速率改变。 (匀速)
动画监听器(AnimationListener)
定义:
是一个监听器,该监听器在动画执行的各个阶段会得到通知,从而调用相应的方法;
方法:
onAnimationEnd(Animation animation) - 当动画结束时调用
onAnimationRepeat(Animation animation) - 当动画重复时调用
onAniamtionStart(Animation animation) - 当动画启动时调用
AnimatorListenerAdapter:
使用这个类就可以解决掉实现接口繁琐的问题;
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
}
});
这里我们向addListener()方法中传入这个适配器对象,由于AnimatorListenerAdapter中已经将每个接口都实现好了,
所以这里不用实现任何一个方法也不会报错。那么如果我想监听动画结束这个事件,就只需要单独重写这一个方法就可以了。
AnimatorSet 和 AnimationSet 的异同
AnimationSet 我们最常用的是调用其 addAnimation 将一个个不一样的动画组织到一起来,
然后调用view 的 startAnimation 方法触发这些动画执行。
功能较弱不能做到把集合中的动画按一定顺序进行组织然后在执行的定制。
AnimatorSet 我们最常用的是调用其play、before、with、after 等方法设置动画的执行顺序,
然后调用其start 触发动画执行。
AnimationSet 与 AnimatorSet 最大的不同在于,
AnimationSet 使用的是 Animation 子类、
AnimatorSet 使用的是 Animator 的子类。
Animation 是针对视图外观的动画实现,动画被应用时外观改变但视图的触发点不会发生变化,还是在原来定义的位置。
Animator 是针对视图属性的动画实现,动画被应用时对象属性产生变化,最终导致视图外观变化。