动画分为属性动画、帧动画、补间动画,接下来我为大家详细解释一下这三种动画
属性动画:
属性动画,又名Property动画,即通过改变对象属性的动画,与补间动画不同的时,属性动画真正改变了一个UI控件,包括其事件触发焦点位置,Android3.0后才有
ValueAnimator 基本属性动画类:
setDuration(long duration)
setEvaluator(TypeEvaluator value)
setFrameDelay(long frameDelay)
setInterpolator(TimeInterpolator value)
addUpdateListener(ValueAnimator.AnimatorUpdateListener listener)
setRepeatCount(int value)
setRepeatMode(int value)
addListener(Animator.AnimatorListener l)
start()
cancel() 停止当前执行的动画,属性值会停止在当前执行位置
end() 结束动画,属性值会停止在结束位置,即使没有播放完动画
举个例子,setEvaluator(TypeEvaluator value):
TypeAnimator通过这个因子计算出属性值,如上例中10ms时:
首先计算出时间因子,即经过的时间百分比:t=10ms/40ms=0.25
经插值计算(inteplator)后的插值因子:大约为0.15,上述例子中用了AccelerateDecelerateInterpolator,计算公式为(input即为时间因子):
(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
最后根据TypeEvaluator计算出在10ms时的属性值:0.15*(40-0)=6pixel。对于TypeEvaluator处理类型为FloatEvaluator时,
其计算方法为 :
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
addUpdateListener(ValueAnimator.AnimatorUpdateListener listener):
接口方法说明:
onAnimationUpdate()
/通过监听这个事件在属性的值更新时执行相应的操作,对于ValueAnimator一般要监听此事件执行相应的动作,不然Animation没意义(可用于计时),在ObjectAnimator(继承自ValueAnimator)中会自动更新属性,如无必要不必监听。在函数中会传递一个ValueAnimator参数,通过此参数的getAnimatedValue()取得当前动画属性值
如下实例:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("update", ((Float) animation.getAnimatedValue()).toString());
}
});
animation.setInterpolator(new CycleInterpolator(3));
animation.start();
addListener(Animator.AnimatorListener l):
通常继承AnimatorListenerAdapter而不是实现AnimatorListener接口来简化操作,如下:
ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);
oa.setDuration(3000);
oa.addListener(new AnimatorListenerAdapter(){
public void on AnimationEnd(Animator animation){
Log.i("Animation","end");
}
});
oa.start();
其中还有ObjectAnimator 对象属性动画类、AnimatorSet 属性动画集合类
ObjectAnimator 对象属性动画类,父类是 ValueAnimator
ofFloat(object target, String property, float... values)详解:
ObjectAnimator
继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了 Property Animation的全部两步操作。实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性,但用ObjectAnimator有一 定的限制,要想使用ObjectAnimator,应该满足以下条件:
对象应该有一个setter函数:set<PropertyName>(驼峰命名法)
如下面的例子中,像ofFloat之类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果values…参数只设置了 一个值的话,那么会假定为目的值,属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的getter方 法:get<PropertyName>
如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。
如果上述条件不满足,则不能用ObjectAnimator,应用ValueAnimator代替。
tv=(TextView)findViewById(R.id.textview1);
btn=(Button)findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);
oa.setDuration(3000);
oa.start();
}
});
动画效果:
把一个TextView的透明度在3秒内从0变至1。
根据应用动画的对象或属性的不同,可能需要在onAnimationUpdate函数中调用invalidate()函数刷新视图。
第二参数常用属性:
RotationY:沿Y轴旋转
TranslationY沿Y轴移动
alpha,透明
示例代码
ObjectAnimator.ofFloat(btn, "TranslationX", 100).setDuration(2000).start();
ofPropertyValuesHolder(object tararget,PropertyValuesHolder p1,PropertyValuesHolderp2):
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("RotationX", 360f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("RotationY", 360f);
ObjectAnimator.ofPropertyValuesHolder(btn, p1, p2).setDuration(2000).start();
clone()
AnimatorSet 属性动画集合类:
通过AnimationSet应用多个动画
AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。
以下例子同时应用5个动画:
1. 播放anim1;
2. 同时播放anim2,anim3,anim4;
3. 播放anim5。
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(anim1).before(anim2);
bouncer.play(anim2).with(anim3);
bouncer.play(anim2).with(anim4)
bouncer.play(anim5).after(amin2);
animatorSet.start();
再来讲一下帧动画:
帧动画,又名Drawable动画,多个图片连续播放,类似gif
核心类:AnimationDrawable
使用步骤:
1,在res文件夹下创建brawable文件夹,用来存放图片资源
2,在brawable文件夹下,创建资源名为mybitmap的<animation-list>文件
写一些简单的代码和注释方便理解:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<!--按顺序和时间播放图片 android:oneshot="true" 动画停止时保持最后一帧-->
<item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
<!--android:drawable="@drawable/rocket_thrust1",当前展示图片是rocket_thrust1-->
<!--android:duration="200",当前展示图片展示时长,以毫秒为单位-->
</animation-list>
<!--帧动画按照item的先后顺序播放动画,较为消耗手机资源,不建议大量使用-->
3,获得当前图片,强制装换为AnimationDrawable的对象
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust); //将帧动画资源文件作为View控件背景
rocketAnimation = (AnimationDrawable) rocketImage.getBackground(); //获取背景并强转成为帧动画对象
4,在适当的地方使用获得到的AnimationDrawable对象调用start()方法启动这个动画
rocketAnimation.start();启动动画
接下来就是补间动画,补间动画,又名View动画,对场景里的对象不断的进行图像变化来产生动画效果,主要有为旋转、平移、缩放和渐变等动画
核心类:Animation与AnimationUtils;重要标签alpha,rotate,translate,scale,set
使用方法:
1,在res文件夹下创建anim文件夹,用来存放属性动画资源
2,创建动画
透明动画:在anim文件夹下,创建资源名为my_anim的<alpha>文件
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0"
android:toAlpha="0.9"
android:duration="3000" >
</alpha>
<!-- fromAlpha 属性为动画起始时透明度
toAlpha 属性为动画结束时透明度
说明:
0.0表示完全透明
1.0表示完全不透明
以上值取0.0-1.0之间的float数据类型的数字长整型值
-->
<!-- duration动画执行时间,以毫秒为单位 -->
旋转动画:在anim文件夹下,创建资源名为my_anim的<rotate>文件
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fromDegrees="0"
android:toDegrees="+350"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="2"
android:repeatMode="restart"
/>
<!--
rotate 旋转动画效果
浮点数型值:
fromDegrees 属性为动画起始时物件的角度
toDegrees 属性为动画结束时物件旋转的角度 可以大于360度
说明:
当角度为负数——表示逆时针旋转
当角度为正数——表示顺时针旋转
(负数from——to正数:顺时针旋转)
(负数from——to负数:逆时针旋转)
(正数from——to正数:顺时针旋转)
(正数from——to负数:逆时针旋转)
pivotX 属性为动画相对于物件的X坐标的开始位置
pivotY 属性为动画相对于物件的Y坐标的开始位置
说明: 以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
duration 属性为动画持续时间时间以毫秒为单位
repeatMode:重复模式(restart:重新启动,reverse:反向启动)
repeatCount:重复数量
-->
<!-- accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。 -->
平移动画:在anim文件夹下,创建资源名为my_anim的<translate>文件
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="1"
android:toXDelta="50"
android:fromYDelta="1"
android:toYDelta="100"
android:duration="3000"
android:repeatCount="2"
android:repeatMode="reverse"
android:interpolator="@android:anim/accelerate_interpolator">
</translate>
<!-- translate 位置转移动画效果
整型值:
fromXDelta 属性为动画起始时 X坐标上的位置
toXDelta 属性为动画结束时 X坐标上的位置
fromYDelta 属性为动画起始时 Y坐标上的位置
toYDelta 属性为动画结束时 Y坐标上的位置
注意:
没有指定fromXType toXType fromYType toYType 时候,
默认是以自己为相对参照物
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
-->
缩放动画:在anim文件夹下,创建资源名为my_anim的<scale >文件
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1"
android:toXScale="3"
android:fromYScale="1"
android:toYScale="6"
android:pivotX="1"
android:pivotY="1"
android:repeatCount="3"
android:duration="4000"
android:repeatMode="restart"
android:interpolator="@android:anim/overshoot_interpolator" >
</scale>
<!-- 尺寸伸缩动画效果 scale
浮点型值:
fromXScale 属性为动画起始时 X坐标上的伸缩尺寸
toXScale 属性为动画结束时 X坐标上的伸缩尺寸
fromYScale 属性为动画起始时Y坐标上的伸缩尺寸
toYScale 属性为动画结束时Y坐标上的伸缩尺寸
说明:
以上四种属性值
0.0表示收缩到没有
1.0表示正常无伸缩
值小于1.0表示收缩
值大于1.0表示放大
pivotX 属性为动画相对于物件的X坐标的开始位置
pivotY 属性为动画相对于物件的Y坐标的开始位置
说明:
以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
布尔型值:
fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用 -->
组合动画:在anim文件夹下,创建资源名为my_anim的<set>文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:repeatCount="2"
android:repeatMode="reverse">
<alpha
android:duration="2000"
android:fromAlpha="0"
android:toAlpha="1" />
<rotate
android:duration="3000"
android:fromDegrees="30"
android:pivotX="5"
android:pivotY="10"
android:toDegrees="270" />
<scale
android:duration="1000"
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="2"
android:toYScale="3" />
<translate
android:duration="3000"
android:fromXDelta="10"
android:fromYDelta="20"
android:toXDelta="100"
android:toYDelta="300" />
</set>
动画的相关类
Animation 动画
AlphaAnimation 渐变透明度
//初始化:第一个参数fromAlpha表示动画起始时的透明度, 第二个参数toAlpha表示动画结束时的透明度
Animation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
//设置动画时间
alphaAnimation.setDuration(3000);
view.startAnimation(alphaAnimation);
RotateAnimation 画面旋转
//第一个参数fromDegrees表示动画起始时的角度, 第二个参数toDegrees表示动画结束时的角度
Animation rotateAnimation = new RotateAnimation(0f, 360f);
rotateAnimation.setDuration(1000);
this.startAnimation(rotateAnimation);
//另外还可以设置伸缩模式pivotXType、pivotYType, 伸缩动画相对于x,y 坐标的开始位置pivotXValue、pivotYValue等
ScaleAnimation 渐变尺寸缩放
//初始化
Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f);
//设置动画时间
scaleAnimation.setDuration(500);
this.startAnimation(scaleAnimation);
第一个参数fromX ,第二个参数toX:分别是动画起始、结束时X坐标上的伸缩尺寸。
第三个参数fromY ,第四个参数toY:分别是动画起始、结束时Y坐标上的伸缩尺寸。
另外还可以设置伸缩模式pivotXType、pivotYType, 伸缩动画相对于x,y 坐标的开始位置pivotXValue、pivotYValue等。
TranslateAnimation 位置移动
//初始化
Animation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);
//设置动画时间
translateAnimation.setDuration(1000);
this.startAnimation(translateAnimation);
第一个参数fromXDelta ,第二个参数toXDelta:分别是动画起始、结束时X坐标。
第三个参数fromYDelta ,第四个参数toYDelta:分别是动画起始、结束时Y坐标。
AnimationSet 动画集合
常用的Interpolator
@android:anim/accelerate_decelerate_interpolator" 先加速后减速
@android:anim/accelerate_interpolator 开始慢,结束快
@android:anim/decelerate_interpolator 开始快,结束慢
@android:anim/decelerate_interpolator 开始快,结束慢
@android:anim/anticipate_interpolator 开始时会超出起始位置,再执行动画
@android:anim/overshoot_interpolator 结束时会超出终止位置,再结束动画
@android:anim/anticipate_overshoot_interpolator 开始和结束时都会超出一定距离
@android:anim/bounce_interpolator 结束时,有反弹效果
@android:anim/cycle_interpolator 动画按特定的次数执行多次,有振动效果
详细分析:
动画资源文件:/res/amin/shake.xml
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="10"
android:duration="1000" android:interpolator="@anim/cycle_7" />
插值器文件:/res/anim/cycle_7.xml
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:cycles="7" />
核心代码中:
Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
EditText et=(EditText)findViewById(R.id.pw);
et.startAnimation(shake);
布局文件:/res/layout/login.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="10dip"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:text="@string/animation_1_instructions"
/>
<EditText android:id="@+id/pw"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:singleLine="true"
android:password="true"
/>
<Button android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/googlelogin_login"
/>
</LinearLayout>
@android:anim/linear_interpolator 均匀的速度执行动画
3,让一个UI控件执行该动画
ImageView iv=(ImageView) findViewById(R.id.iv);
//获得一个动画
Animation anim = AnimationUtils.loadAnimation(this, R.anim.my_anim);
//启动这个动画
iv.startAnimation(anim);