1. animation简述
Android动画分为三种:view动画、帧动画和属性动画,帧动画也属于View动画的一种,不过它和平移、旋转等常见的view动画在表现形式上略有不同;
View动画通过对场景里的对象不断做图像变换(平移、缩放、旋转、透明度)从而产生动画效果,是一种渐进式动画,并且view动画支持自定义
帧动画通过顺序播放一系列图像从而产生动画效果,可以理解为图片切换动画,如果图片过多过大就会导致OOM
属性动画通过动态的改变对象的属性从而达到动画效果,属性动画为API11新特性,低版本通过兼容库来使用它
2. View动画
View动画的作用对象是View, 它支持4种动画效果,分别是平移动画、缩放动画、旋转动画和透明度动画。除了这四种典型的变换效果外,帧动画也属于View动画,但是帧动画的表现形式和上面的四种变换效果不太一样。
2.1 View动画的种类
四种动画既可以通过xml来定义(可读性好),也可以通过代码来动态创建
动画描述文件:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true"
android:fillAfter="true">
<translate
android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta="float"/>
<scale
android:fromXScale="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float"/>
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotY="float"
android:pivotX="float"/>
<alpha
android:fromAlpha="float"
android:toAlpha="float"/>
</set>
< set>标签表示动画集合,对应AnimationSet类,它可以包含若干个动画,并且它的内部也是可以嵌套其他动画集合的,属性的含义如下:android:interpolator
表示动画集合所采用的插值器,插值器影响动画的速度,比如非匀速动画就需要通过插值器来控制动画的播放过程。这个属性可以不指定,默认为@androidanin/accelerate_decelerate_interpolator
, 即加速减速插值器android:shareInterpolator
表示集合中的动画是否和集合共享同一个插值器。如果集合不指定插值器,那么子动画就需要单独指定所需的插值器或者使用默认值。android:duration
动画的持续时间android:fillafter
动画结束之后view是否停留在结束位置 true表示view停留android:zAdjustment
:允许在动画播放期间,调整播放内容在Z轴方向的顺序
①normal (0): 正在播放的动画内容保持当前的Z轴顺序
②top (1): 在动画播放期间,强制把当前播放的内容放到其他内容的上面
③bottom (-1): 在动画播放期间,强制把当前播放的内容放到其他内容之下
< translate>
:表示平移动画,对应TranslateAnimation类。
android:fromXDelta:动画起始时X坐标上的位置。
android:toXDelta:动画结束时X坐标上的位置。
android:fromYDelta:动画起始时Y坐标上的位置。
android:toYDelta:动画结束时Y坐标上的位置。
< scale>
:表示缩放动画,对应ScaleAnimation类。
android:fromXScale动画起始时X坐标上的伸缩尺寸。
android:toXScale:动画结束时X坐标上的伸缩尺寸 。
android:fromYScale:动画起始时Y坐标上的伸缩尺寸。
android:toYScale:属性为动画结束时Y坐标上的伸缩尺寸。
android:pivotX:动画相对于物件的X坐标的开始位置。
android:pivotY:动画相对于物件的Y坐标的开始位置。
前四个属性值的值含义:
- 值=0.0 :表示收缩到没有
- 值<1.0 :表示收缩
- 值=1.0 :表示无伸缩
- 值>1.0 :表示放大
后两个属性值表示缩放的轴点:从0%-100%中取值。
< rotate>
:表示旋转动画,对应RotateAnimation类。
android:fromDegrees:动画起始时物件的角度 。
android:toDegrees:动画结束时物件旋转的角度。
以上两个属性共同确定旋转方向,原则是:当角度为负数时表示逆时针旋转,反之。故共存在以下四种情况:
- from=负数->to=正数:表示顺时针旋转
- from=负数->to=负数:表示逆时针旋转
- from=正数->to=正数:表示顺时针旋转
- from=正数->to=负数:表示逆时针旋转
android:pivotY:动画相对于物件的X坐标的开始位置。
android:pivotX:动画相对于物件的Y坐标的开始位置。
以上两个属性值表示旋转的轴点:从0%-100%中取值。
< alpha>
:表示透明度动画,对应AlphaAnimation类。
android:fromAlpha:动画起始时透明度。
android:toAlpha动画结束时透明度。
以上两个属性值:从0-1中取值。
- 值=0.0 :表示完全透明
- 值=1.0 :表示完全不透明
使用步骤:
1.通过xml文件定义动画 或 代码定义动画
2.设置一个view
3.为view加载这个动画
Button button1= (Button)findViewById(R. id. buttonI) ;
Animation animation=Animat ionUtils.loadAnimatior(this, R.anim.animation_test) :
buttonl.startAnimation(animation) ;
Button button1= (Button)findViewById(R.id.buttonI) ;
AlphaAnimation alphaAnimation=new AlphaAnimation(O, 1) ;
alphaAnimation.setDuration(3000) ;
buttonl.startAnimation(alphaAnimation) ;
4.同时对于动画时间,android也提供了开始、结束和重复时间的监听方法
public static interface AnimationListener {
//动画开始
void onAnimationStart(Animator animation);
//动画结束
void onAnimationEnd(Animator animation);
//动画重复
void onAnimationRepeat(Animator animation);
}
2.2 自定义View动画
步骤:继承Animation- >重写initialize()
和applyTransformation()
方法:initialize(用于初始化); applyTransformation()用于进行矩阵变换
2.3 View动画的特殊使用场景
1.布局动画LayoutAnimation
作用于ViewGroup,为ViewGroup指定一个动画,当它的子元素出场时都具有该动画效果
(1) 定义LayoutAnimation
(2) 为元素指定具体的入场动画 anim_item.xml
(3) 为ViewGroup指定android:layoutAnimation属性
2.activity的切换效果
Activity有默认的切换效果,但是这个效果我们是可以自定义的,主要用到
overridePendingTransition(int enterAnim, int exitAnim)
这个方法,这个方法必须在startActivity(Intent)
或者finish()
之后被调用才能生效,它的参数含义如下:
enterAnim----Activity被打开时,所需的动画资源id;
exitAnim----Activity被暂停时,所需的动画资源id.
启动活动时:
结束活动时:
3. 帧动画
帧动画是顺序播放一组通过xml预先定义好的图片,类似于电影播放。不同于View动画,系统提供了另外一个类AnimationDrawable来使用帧动画。
4. 属性动画
使用属性动画的前提:
开源动画库:http://nineoldandroids.com/
导入开源动画库:implementation 'com.nineoldandroids:library:2.4.0'
4.1 插值器和估值器
TimeInterpolator
时间插值器
- 作用:根据时间流逝的百分比计算出当前属性值改变的百分比。确定了动画效果变化的模式,如匀速变化、加速变化
- 常用的系统内置插值器:
线性插值器(LinearInterpolator):匀速动画
加速减速插值器(AccelerateDecelerateInterpolator):动画两头慢中间快
减速插值器(DecelerateInterpolator):动画越来越慢 - 可针对的对象
View动画:插值器对应的属性是android:interpolator。
属性动画:是实现非匀速动画的重要手段。 - 自定义插值器方法:实现 Interpolator / TimeInterpolator接口 ,然后复写getInterpolation()。
TypeEvaluator
类型估值器
- 作用:根据当前属性改变的百分比计算出改变后的属性值。
- 常用的系统内置的估值器:
整形估值器(IntEvaluator)
浮点型估值器(FloatEvaluator)
Color属性估值器(ArgbEvaluator) - 针对于属性动画,View动画不需要类型估值器。是属性动画实现非匀速动画的重要手段。
- 自定义估值器方法:实现TypeEvaluator接口,然后复写evaluate()。
4.2 属性动画的工作原理
在一定时间间隔内,通过不断对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在该属性上的动画效果,get方法和set方法都是通过反射来调用的
step1:创建属性动画时,若未设置属性的初始值,则系统会通过该属性的get()方法获取初始值。故属性动画要求必须提供属性的get()方法。
step2: 在动画播放的过程中,利用时间插值器和类型估值器获取改变后的属性值。
step3:将改变后的属性值通过set()方法设置到对象中。故属性动画要求必须提供属性的set()方法。
4.3 属性动画的实现方式
在res/animator/下可创建属性动画的xml文件。其中,根节点<set>
对应AnimatorSet
类,子节点<objectAnimator>
对应ObjectAnimator
类、<animator>
对应ValueAnimator
类。常用属性:
<set
android:ordering=["together" | "sequentially"]>
<objectAnimator
android:propertyName="string"
android:duration="int"
android:valueFrom="float | int | color"
android:valueTo="float | int | color"
android:startOffset="int"
android:repeatCount="int"
android:repeatMode=["repeat" | "reverse"]
android:valueType=["intType" | "floatType"]/>
<animator
android:duration="int"
android:valueFrom="float | int | color"
android:valueTo="float | int | color"
android:startOffset="int"
android:repeatCount="int"
android:repeatMode=["repeat" | "reverse"]
android:valueType=["intType" | "floatType"]/>
<set>
...
</set>
</set>
android:ordering
:设置动画的时序关系。可选值:together
:默认值。表示动画集合中的子动画同时播放。sequentially
:表示动画集合中的子动画按照书写的先后顺序依次播放。
1.通过ObjectAnimator
实现属性动画
- 原理:通过直接对对象(object)的属性值进行改变操作,从而实现动画效果
- 常用属性:
①android:propertyName
:属性动画作用的属性名称。
②android:duration
: 动画持续时长。
③android:startOffset
:设置动画执行之前的等待时长。
④android:repeatCount
:动画重复执行的次数。
默认为0,表示只播放一次;设置为-1或infinite,表示无限重复。
⑤android:repeatMode
:动画重复执行的模式。可选值:
restart:表示连续重复,为默认值;reverse :表示逆向重复。
⑥android:valueFrom
:动画初始值。
⑦android:valueTo
:动画结束值。
⑧android:valueType
:动画值类型。可选值:
intType :以上两个value属性值为整型。
floatType:即以上两个value属性值为浮点型,为默认值。
若为color值,则无需设置该属性。
2.通过ValueAnimator
实现属性动画
- 原理:通过不断控制值(value)的变化,再不断手动赋给对象的属性,从而实现动画效果。
- ObjectAnimator与 ValueAnimator类的区别:
ValueAnimator 类是先改变值,然后手动赋值给对象的属性从而实现动画;是间接对对象属性进行操作;
ObjectAnimator 类是先改变值,然后自动赋值给对象的属性从而实现动画;是直接对对象属性进行操作; - 对应根节点
<animator>
常用属性比标签少一个android:propertyName属性,其他相同。
4.4 属性动画的监听器
属性动画主要使用两个接口:AnimatorUpdateListener&AnimatorListener来监听动画的播放过程。
AnimatorListener :监听动画的开始、结束、取消以及重复播放。如下:
public static interface AnimatorListener {
void onAnimationStart(Animator animation); //动画开始
void onAnimationEnd(Animator animation); //动画结束
void onAnimationCancel(Animator animation); //动画取消
void onAnimationRepeat(Animator animation); //动画重复播放
}
AnimatorListener
可以监听动画的开始、结束、取消以及重复播放。同时为了方便开发,系统还提供了AnimatorListenerAdapter
这个类,它是AnimatorListener
的适配器类,这样我们就可以有选择地实现上面的4个方法了
AnimatorUpdateListener :监听整个动画过程。动画是由许多帧组成的,每播放一帧,onAnimationUpdate
就会被调用一次
public interface AnimatorUpdateListener {
void onAnimationUpdate(ValueAnimator var1);//在属性动画的属性值变化是回调。
}
5. 动画相关问题
set方法无法对UI进行修改
针对部分View的set方法对属性的改变没有带来UI的改变,提出三种解决方案:
- 给对象加上get和set方法(在有权限的前提下)
- 使用ViewWrapper等包装类对原始View对象进行包装,间接提供get和set方法;在set方法中对属性进行动画设置
private void performAnimate() (
ViewWrapper wrapper = new ViewWrapper (mButton);
objectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();
@Override
public void onClick(View v) (
if (v==mButton)
performAnimate() ;
}
private static class ViewWrapper {
private Vlev mTarget:
public Viewrapper(View target) {
mTarget = target;}
public int getwidth() {
return mTarget.getLayoutParams().width;}
public void setWidth(int width) {
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
- 采用ValueAnimator,监听动画过程,自己实现属性的改变
注意事项