Android动画系列之属性动画(Property Animation)详解
Android动画系列之属性动画(Property Animation)详解
1、简介
属性动画可以让任何对象加上动画效果。可以定义一个动画来改变任何对象属性,无论它是否显示在屏幕上。在指定的时间长度,属性动画改变属性值。通过指定对象属性来创造动画效果,比如View在屏幕上的位置,动画的时长,以及动画值的改变。
属性动画系统可以让定义一个动画的以下特征:
- 持续时间(Duration):可以指定一个动画的持续时间。默认长度为300毫秒。
- 时间插值器(Time interpolation):可以指定属性的值如何计算作为动画当前所用时间的函数。
- 重复和行为(Repeat count and behavior):可以指定是否有一个动画重复时,达到持续时间的结束,有多少次重复动画。您还可以指定是否希望动画反向播放。设置它反向播放动画,然后反复重复,直到达到重复的数量。
- 动画设置(Animator Sets):可以让动画成逻辑组,同时或顺序或在指定的延迟。
- 帧刷新延迟(Frame refresh delay):可以指定如何经常刷新动画帧。默认设置为刷新每10毫秒,但应用程序可以刷新帧的速度最终取决于系统的整体是如何的,以及该系统可以为底层定时器服务的速度。 一般使用系统默认即可。
2、属性动画与补间动画的区别
补间动画只能作用于View对象,所以如果您想要作用于非View对象时,必须实现自己的代码。视图动画系统也受到限制,因为它只公开了View对象来动画,例如视图的缩放和旋转,而不是背景色。
补间动画的另一个缺点是它只修改了视图绘制的位置,而不是实际视图本身。例如,如果您动画一个按钮以在屏幕上移动,则该按钮的绘制正确,但是您可以单击该按钮的实际位置不会改变,因此您必须实现自己的逻辑来处理这个问题。
使用属性动画,这些约束将被完全解除,您可以对任何对象(视图和非视图)的任何属性进行动画化,并且对象本身实际上是被修改的。从更高层次上来说,您可以为要动画的属性(如颜色、位置或大小)添加动画,并可以定义动画的各个方面,如通过插值器或者多个动画的同步。
然而,补间动画需要更少的时间来设置,并且需要更少的代码来编写。如果补间动画完成了您需要做的所有事情,或者您的现有代码已经按照您想要的方式工作,则不需要使用属性动画系统。所以,根据不同场合来选择合适的动画,是最好的选择。
3、API概述
3.1、ValueAnimator
这是整个属性动画的核心类,它封装了为动画设置起始值、结束值、持续时间以及如何重复等方法 ,当然还有监听变化值的回调方法。但是,ValueAnimator并没有将实时监听的变化值设置到目标对象的指定属性上,所以您必须手动设置。
3.1.1、ValueAnimator主要方法:
- addUpdateListener(ValueAnimator.AnimatorUpdateListener listener):
- getAnimatedValue():获取只有一个属性时的动画当前进行值
- getAnimatedValue(String propertyName):根据属性名称获取当前的动画进行值
- ofArgb(int… values):构造并返回在颜色值之间ValueAnimator对象
- ofFloat(float… values):构造并返回在浮点值之间ValueAnimator对象
- ofInt(int… values):构造并返回在整型之间ValueAnimator对象
- ofObject(TypeEvaluator evaluator, Object… values):构造并返回在对象之间ValueAnimator对象
- ofPropertyValuesHolder(PropertyValuesHolder… values):构造并返回在PropertyValuesHolder对象中指定的值之间的ValueAnimator对象,用于实现实现组合动画
3.1.2、ValueAnimator的使用
1、通过几个of方法获取ValueAnimator的实例,并设置属性的变化值开始与结束值;
2、设置动画的播放各种属性,如动画时长,是否循环等;
3、为动画设置监听addUpdateListener,在监听里面获取属性的变化值,将改变后的值赋给对象的属性值,然后刷新视图;
4、启动动画。
下面将通过改变button的宽度这个例子来演示:
/**
* 将btn1的宽度由200px延展到800px
*/
private void ofInt1(){
//1、设置属性数值的初始值 & 结束值
ValueAnimator valueAnimator = ValueAnimator.ofInt(200,800);
//2:设置动画的播放各种属性
valueAnimator.setDuration(3000);
//3、添加监听
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获得每次变化后的属性值
int currentValue = (int) animation.getAnimatedValue();
//手动将变化的值赋给对象的属性
btn1.getLayoutParams().width = currentValue;
//刷新视图
btn1.requestLayout();
}
});
//4、启动动画
valueAnimator.start();
}
ValueAnimator.ofObject()的本质还是操作 * 值 *,只是是采用将 多个值 封装到一个对象里的方式 同时对多个值一起操作而已
3.2、ObjectAnimator
ObjectAnimator是ValueAnimator的子类,可以直接对对象的属性赋值进行操作。一般情况下都是使用ObjectAnimator。
想要正确的使用objectanimator更新属性,必须做到以下几点:
- objectanimator 更新 动画的对象属性必须有一个setter函数的形式设置属性名。因为objectanimator依赖setter函数来自动更新动画,它必须能够与这个setter方法访问属性
。例如想要修改一个属性width,必须存在setWidth方法。如果setter方法不存在,有三个选项:- 如果有权限则将setter方法添加到类中。
- 使用您有权更改的包装类,并让该包装器使用有效的setter方法接收值,并将其转发给原始对象。
- 使用ValueAnimator
- 如果您在调用of方法创建动画时只传入了一个属性值(而不是既有启始值和终止值),那么系统将默认把这个值视为终止值,这就需要该属性包含getter()方法,以获得其初始值,getter()方法的命名规则与setter()方法一致
- getter()方法获取值的类型与setter()方法设置值的类型必须相同
- 实现动画的效果可能需要调用invalidate()方法强制view重绘,这需要在onAnimationUpdate()的回调方法中进行
ObjectAnimator的使用方法是类似ValueAnimator:
//第一个参数是需要设置动画的对象,第二个参数是需要改变的属性名称
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv1,"alpha",0f,1f);
objectAnimator.setDuration(3000);
objectAnimator.start();
常用的ObjectAnimator属性:
属性 | 作用 | 数值类型 |
---|---|---|
alpha | 控制透明度 | float |
rotation | 控制旋转角度 | float |
translationX | x方向的位移 | float |
translationX | y方向的位移 | float |
scaleX | X方向的缩放倍数 | float |
scaleY | Y方向的缩放倍数 | float |
rotationX | 以X轴为轴的旋转度数 | float |
rotationY | 以Y轴为轴的旋转度数 | float |
3.3、AnimatorSet
AnimatorSet播放一组Animator对象按指定的顺序排列。动画可以设置为一起播放,顺序,或在指定的延迟之后。、
AnimatorSet这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
- after(long delay):将现有动画延迟指定毫秒后执行
- after(Animator anim):将现有动画插入到传入的动画之后执行
- before(Animator anim):将现有动画插入到传入的动画之前执行
- with(Animator anim):将现有动画和传入的动画同时执行
4、xml使用属性动画
在xml中一共可以使用三种标签:
- ValueAnimator - animator
- ObjectAnimator - objectAnimator
- AnimatorSet - set
使用的时候在res/animator下新建xml文件
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<animator
android:duration="3000"
android:startOffset="1000"
android:valueFrom="200px"
android:valueTo="800px"
android:valueType="intType"/>
<objectAnimator
android:duration="2000"
android:valueFrom="1"
android:valueType="floatType"
android:valueTo="0"
android:propertyName="alpha"/>
</set>
其中android:ordering=”sequentially”这个属性共有两个值:
- sequentially:按顺序播放
- together:同时播放
在代码中载入动画:
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
animator.setTarget(view);
animator.start();
5、ViewGroup容器布局动画
属性动画系统提供了对ViewGroup对象进行动画化更改的功能,并提供了一种简单的方法来对视图对象本身进行动画化。
控件可以在ViewGroup中通过设置LayoutTransition对布局更改进行动画化。
LayoutTransition的动画效果都是设置给ViewGroup,然后当被设置动画的ViewGroup中添加删除View时体现出来。该类用于当前布局容器中有View添加、删除、隐藏、显示等时候定义布局容器自身的动画和View的动画.
LayoutTransition有下面几种转换类型动画:
- APPEARING:当View出现或者添加的时候View出现的动画
- CHANGE_APPEARING:当添加View导致布局容器改变的时候整个布局容器的动画。
- DISAPPEARING:当View消失或者隐藏的时候View消失的动画
- CHANGE_DISAPPEARING:当删除或者隐藏View导致布局容器改变的时候整个布局容器的动画
- CHANGING:不是由于View出现或消失造成对其他View位置造成改变的时候整个布局容器的动画
使用的时候只要将ViewGroup的android:animateLayoutchanges属性设置为true,即可使用默认的动画:
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/verticalContainer"
android:animateLayoutChanges="true" />
如果要使用自己的自定义动画,可以通过调用LayoutTransition的setAnimator()设置自定义的动画。
具体可参考Android属性动画Property Animation系列三之LayoutTransition(布局容器动画)
6、PropertyValuesHolder与Keyframe
PropertyValuesHolder可以生成操作几个属性的动画,可实现组合动画。
Keyframe关键帧,可以设置对应时间的的值,配合PropertyValuesHolder使用。
详细介绍可参考PropertyValuesHolder与Keyframe
7、StateListAnimator
通过StateListAnimator各种动画的搭配,我们能为不同状态下的控件提供各种动画效果。
StateListAnimator在API21才引入的,所以在5.0以上的系统才有效果。
在res/animator中新建selector文件:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<set>
<objectAnimator android:propertyName="scaleX"
android:duration="@android:integer/config_shortAnimTime"
android:valueTo="1.5"
android:valueType="floatType"/>
<objectAnimator android:propertyName="scaleY"
android:duration="@android:integer/config_shortAnimTime"
android:valueTo="1.5"
android:valueType="floatType"/>
</set>
</item>
<item android:state_pressed="false">
<set>
<objectAnimator android:propertyName="scaleX"
android:duration="@android:integer/config_shortAnimTime"
android:valueTo="1"
android:valueType="floatType"/>
<objectAnimator android:propertyName="scaleY"
android:duration="@android:integer/config_shortAnimTime"
android:valueTo="1"
android:valueType="floatType"/>
</set>
</item>
</selector>
可以在xml文件中设置:
android:stateListAnimator=”@animator/selector_animate_scale”
也可以通过代码设置:
StateListAnimator animator = AnimatorInflater.loadStateListAnimator(this, R.animator.selector_animate_scale);
btnStateListAnim.setStateListAnimator(animator);
8、ViewPropertyAnimator
ViewPropertyAnimator提供一种简单的方法来动画View并行地使用单个基础Animator对象。它的行为很像一个ObjectAnimator,因为它修改视图属性的实际值,但在同时动画多个属性时效率更高。
它的用法如下:
btnViewProperty.animate().x(500).y(500).start();
ViewPropertyAnimator还有好多便捷的方法:
alpha(float value),rotation(float value),scaleX(float value),translationX(float value)等等。
详情见ViewPropertyAnimator API文档
9、插值器和估值器的使用
上一篇: 教你用PHPWIND得到管理员密码的方法
下一篇: 针对SEO的服务器主机购置经验总结