那么接着学习属性动画,之前的ViewAnimation和插值器看了的话,那么谷歌提供的动画效果掌握的差不多了。这里给出之前的文章链接。
- Android动画系列(二)插值器效果:http://blog.csdn.net/sw5131899/article/details/70176382
- Android动画系列(一)ViewAnimation:http://blog.csdn.net/sw5131899/article/details/70162113
- 参考启航自定义控件系列学习:http://blog.csdn.net/harvic880925/article/details/50525521
参考郭霖属性动画学习:http://blog.csdn.net/guolin_blog/article/details/43536355
那么为什么要加入属性动画呢?属性动画和补间动画又有什么区别?(摘抄自启航博客)
1.Property Animation能实现补间动画无法实现的功能 ,比如实现控件背景颜色改变。
2.View Animation仅能对指定的控件做动画,而Property Animator是通过改变控件某一属性值来做动画的。
3.补间动画虽能对控件做动画,但并没有改变控件内部的属性值。而Property Animator则是恰恰相反,Property Animator是通过改变控件内部的属性值来达到动画效果的
不知道使用补间动画的各位有没有遇到一个问题。就是控件移动了,但是它的属性却没有改变。比如一个按钮Button,在屏幕中间,设置了点击事件。随后通过补间动画移动到了上方靠屏幕处,在点击按钮,不会有任何响应,而点击按钮原来的位置会有响应事件。
没把鼠标录进去,将就看吧~~。
那么补间动画和属性动画有什么区别呢?(部分摘抄自启航博客)
首先,直观上,他们有如下四点不同:
1、引入时间不同:View Animation是API Level 1就引入的。Property Animation是API Level 11引入的,即Android 3.0才开始有Property Animation相关的API。
2、所在包名不同:View Animation在包android.view.animation中。而Property Animation API在包 android.animation中。
3、动画类的命名不同:View Animation中动画类取名都叫XXXXAnimation,而在Property Animation中动画类的取名则叫XXXXAnimator
4、存放的位置不同,TweenAnimation存放xml在res/anim/filename.xml。FrameAnimation存放xml在res/drawable/filename.xml。PropertyAnimation 存放在res/animator/filename.xml。也就是在创建xml文件时,需要创建一个animator文件夹在res文件夹下。
Property Animation
属性动画包含了 ValueAnimator, ObjectAnimator,AnimatorSet。那么接下来就分别说他们怎么用的。
拥有的属性及意义:
- set标签,创建的属性动画文件必须有个根,可以是set,objectAnimator或者valueAniamtor。set可以包含多个动画。可以设置android:ordering。ordering拥有两个选择,1、sequentially:顺序执行动画。2、together(默认) :一起执行动画。
ValueAnimator
先讲讲简单的xml应用。因为属性动画更多的是用java类。
根标签是animator。拥有的属性:
android:valueTo(必须设置)。动画结束属性值,可以设置float,int,或者color.color要使用6位数的16进制数表示,例如:#333333
android:valueFrom(必须设置)。动画开始属性值,可以设置float,int,或者color.color要使用6位数的16进制数表示,例如:#333333
android:duration。设置动画时间,毫秒值,int整型数值。若不设置,默认300毫秒。
android:startOffset。int整型数毫秒值。开始延迟,也就是调用了start之后延迟多久才开始。
android:repeatCount。int整型设置重复动画播放的次数。
android:repeatMode。重复模式,reverse:反顺序播放,和restart:从头开始重复播放。
android:valueType。选择改变属性的数值类型,intType:指定动画值是整数。floatType :指定动画值是浮点数。如果改变的是color,那么就不需要设置该属性值。
valueAniamtor更多的是设置值得一个变化过程。比如一个值从0到100的变化。
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="100"
android:duration="3000"
android:valueType="intType">
</animator>
再来看看使用java类来实现。那么看看ValueAnimator的一些常用方法。
谷歌官方ValueAnimator类的介绍:https://developer.android.com/reference/android/animation/ValueAnimator.html
addUpdateListener(ValueAnimator.AnimatorUpdateListener listener) 添加动画执行监听回调。
cancel() ,取消动画。
getAnimatedValue() ,这是个很重要的方法,在监听回调中获取正在改变的value值。
isRunning() ,是否在正在运行。
isStarted() ,判断是否已经结束。
ofFloat(float… values) ,变化值以float
ofInt(int… values) ,变化值以int整型
ofArgb(int… values) ,变化值是颜色
pause() ,暂停属性变化动画
reverse() ,动画翻转播放
start() ,开始执行动画。还有很多其他方法,可以去官方文档查看。
ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
valueAnimator.setDuration(3000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("tag00","当前属性值:"+animation.getAnimatedValue());
image.setTranslationX((Float) animation.getAnimatedValue());
}
});
valueAnimator.start();
看看打印的结果:
在监听回调中,设置图片的位置。
那么ValueAnimator简单的使用就这些了。是不是很简单,顺着学习一遍,就会了。哈哈~~
ObjectAnimator
那么先来看看objectAnimator标签有什么属性,只要弄明白了xml属性值得意义,那么java对应的方法,也就明白了。
- android:propertyName(必须设置):动画变化的属性值名称,字符串形式。比如“alpha”,“backgroundColor”,“rotation”,那么这些怎么来的呢。下面的表格中注释的,都是可以设置的名称
//1、透明度:alpha
public void setAlpha(float alpha)
//2、旋转度数:rotation、rotationX、rotationY
public void setRotation(float rotation)
public void setRotationX(float rotationX)
public void setRotationY(float rotationY)
//3、平移:translationX、translationY
public void setTranslationX(float translationX)
public void setTranslationY(float translationY)
//缩放:scaleX、scaleY
public void setScaleX(float scaleX)
public void setScaleY(float scaleY)
android:valueTo(必须设置):动画属性值变化结束时的值。
android:valueFrom(必须设置):动画属性值变化的起点值,可以设置int,float,和color,若是color,需要设置6位16进制的数,比如 #333333
android:duration:动画执行时间,毫秒值
android:startOffset:开始延迟时间,当调用了start之后,不会立刻执行动画,会延迟startOffset时间在执行。
android:repeatCount:重复播放的次数
android:repeatMode:重复模式。reverse或者restart。
android:valueType:intType或者floatType。
这些是objectAniamtor的基础属性。那么先来写个简单的例子。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together"
>
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="0.0"
android:valueTo="500.0"
android:interpolator="@android:anim/bounce_interpolator"
android:valueType="floatType"
>
</objectAnimator>
</set>
这里设置了一个插值器,至于插值器效果可以去之前的文章去看。这里看一下效果。
那么在来看看java类的ObjectAnimator的一些常用方法简介,参照着谷歌官方文档。
ofArgb(Object target, String propertyName, int… values) ,设置颜色为属性动画。target:执行动画的对象,propertyName:xml属性值中的propertyName,设置属性名。values:颜色具体值
ofInt(Object target, String propertyName, int… values),target:执行动画的对象,propertyName:xml属性值中的propertyName,设置属性名。values:具体值
setDuration(long duration) ,设置播放时长
setTarget(Object target) ,设置动画执行对象
start() ,开始执行动画。
同时ObjectAnimator继承ValueAnimator。那么ValueAnimator有的方法,ObjectAnimator都是可以使用的。还有很多其他方法,不过这里只介绍基础使用方法,所以那些比较复杂的方法,留着下次有空整理整理。
ObjectAnimator animator = ObjectAnimator.ofFloat(text,"translationY",0.0f,-300f);
animator.setDuration(3000);
animator.setInterpolator(new BounceInterpolator());
animator.start();
那么来看看效果
运用是不是很简单,感觉和ViewAnimation没什么区别,对吗》不不不,其实区别相当大。就像最开始的那个按钮,如果使用属性动画,那么就不会出现点击范围不正常的错误了。属性动画基本可以干viewanimation所有的事。而且还能干更多的事。Property Animation还可以设置path,按照path来运行。会在后面讲到。
那么来一个复杂点的综合动画的例子。
综合使用
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially"
>
<!--运行之前 放大1.2 旋转720度-->
<set android:ordering="together">
<objectAnimator
android:propertyName="scaleX"
android:valueFrom="0.0"
android:valueTo="1.2"
android:valueType="floatType"
android:duration="2000">
</objectAnimator>
<objectAnimator
android:propertyName="scaleY"
android:valueFrom="0.0"
android:valueTo="1.2"
android:valueType="floatType"
android:duration="2000">
</objectAnimator>
<objectAnimator
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="720"
android:valueType="floatType"
android:duration="2000">
</objectAnimator>
</set>
<!-- 右移 300-->
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="0.0"
android:valueTo="300.0"
android:interpolator="@android:anim/bounce_interpolator"
android:valueType="floatType"
>
</objectAnimator>
<!-- 闪烁4S -->
<objectAnimator
android:duration="2000"
android:propertyName="alpha"
android:valueFrom="1.0"
android:valueTo="0.0"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueType="floatType">
</objectAnimator>
<!--向上运行400 缩小到0.5 -->
<set
android:ordering="together">
<objectAnimator
android:propertyName="translationY"
android:valueFrom="0.0"
android:valueTo="-400.0"
android:duration="2000"
android:valueType="floatType"
>
</objectAnimator>
<objectAnimator
android:propertyName="scaleX"
android:valueFrom="1.2"
android:valueTo="0.5"
android:valueType="floatType"
android:duration="2000"
>
</objectAnimator>
<objectAnimator
android:propertyName="scaleY"
android:valueFrom="1.2"
android:valueTo="0.5"
android:valueType="floatType"
android:duration="2000"
>
</objectAnimator>
</set>
<set android:ordering="together">
<objectAnimator
android:propertyName="translationY"
android:valueFrom="0.0"
android:valueTo="400.0"
android:duration="2000"
android:valueType="floatType">
</objectAnimator>
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="0.0"
android:valueTo="-300.0"
android:valueType="floatType"
>
</objectAnimator>
<objectAnimator
android:propertyName="scaleX"
android:valueFrom="0.5"
android:valueTo="1.0"
android:valueType="floatType"
android:duration="2000"
>
</objectAnimator>
<objectAnimator
android:propertyName="scaleY"
android:valueFrom="0.5"
android:valueTo="1.0"
android:valueType="floatType"
android:duration="2000"
>
</objectAnimator>
</set>
</set>
看一下具体效果。
那么也想看看使用java类怎么来实现。
AnimatorSet animatorSet = new AnimatorSet();
//原地动画
ObjectAnimator animatorscaleX = ObjectAnimator.ofFloat(text,"scaleX",0.0f,1.2f);
animatorscaleX.setDuration(2000);
ObjectAnimator animatorscaleY = ObjectAnimator.ofFloat(text,"scaleY",0.0f,1.2f);
animatorscaleY.setDuration(2000);
ObjectAnimator animatorrotation = ObjectAnimator.ofFloat(text,"rotation",0f,720f);
animatorrotation.setDuration(2000);
AnimatorSet animatorSet1 = new AnimatorSet();
animatorSet1.playTogether(animatorscaleX,animatorscaleY,animatorrotation);
//向右移动
float value = text.getTranslationX();
ObjectAnimator animatortranslationX = ObjectAnimator.ofFloat(text,"translationX",value,300f);
animatortranslationX.setInterpolator(new BounceInterpolator());
animatortranslationX.setDuration(2000);
//原地闪烁
ObjectAnimator animatoralpha = ObjectAnimator.ofFloat(text,"alpha",1.0f,0.0f);
animatoralpha.setRepeatCount(1);
animatoralpha.setRepeatMode(ValueAnimator.REVERSE);
animatoralpha.setDuration(2000);
//向上移动
float value1 = text.getTranslationY();
ObjectAnimator animatortranslationY = ObjectAnimator.ofFloat(text,"translationY",value1,-400f);
animatortranslationY.setDuration(2000);
ObjectAnimator animatorscaleX1 = ObjectAnimator.ofFloat(text,"scaleX",1.2f,0.5f);
animatorscaleX1.setDuration(2000);
ObjectAnimator animatorscaleY1 = ObjectAnimator.ofFloat(text,"scaleY",1.2f,0.5f);
animatorscaleY1.setDuration(2000);
AnimatorSet animatorSet2 = new AnimatorSet();
animatorSet2.playTogether(animatortranslationY,animatorscaleX1,animatorscaleY1);
//向左移动
float value3 = text.getTranslationX();
ObjectAnimator animatortranslationX1 = ObjectAnimator.ofFloat(text,"translationX",value3,-300f);
animatortranslationX1.setDuration(2000);
ObjectAnimator animatorscaleX2 = ObjectAnimator.ofFloat(text,"alpha",1.0f,0.5f);
animatorscaleX2.setDuration(2000);
AnimatorSet animatorSet3 = new AnimatorSet();
animatorSet3.playTogether(animatortranslationX1,animatorscaleX2);
//回到原来位置
float value2 = text.getTranslationY();
ObjectAnimator animatortranslationY1 = ObjectAnimator.ofFloat(text,"translationY",value2,400f);
animatortranslationY1.setDuration(2000);
ObjectAnimator animatorscaleX3 = ObjectAnimator.ofFloat(text,"alpha",0.5f,1.0f);
animatorscaleX3.setDuration(2000);
AnimatorSet animatorSet4 = new AnimatorSet();
animatorSet4.playTogether(animatortranslationY1,animatorscaleX3);
animatorSet.playSequentially(animatorSet1,animatortranslationX,animatoralpha,animatorSet2,animatorSet3,animatorSet4);
animatorSet.start();
再来看看效果。
那么属性动画简单的使用就这么多了,然而属性动画不只这样,有空会在去总结属性动画。