android 30 以后3种动画.docx
- 文档编号:6532149
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:12
- 大小:139.16KB
android 30 以后3种动画.docx
《android 30 以后3种动画.docx》由会员分享,可在线阅读,更多相关《android 30 以后3种动画.docx(12页珍藏版)》请在冰豆网上搜索。
android30以后3种动画
3.0以前,android支持两种动画模式,tweenanimation,frameanimation,在android3.0中又引入了一个新的动画系统:
propertyanimation,这三种动画模式在SDK中被称为propertyanimation,viewanimation,drawableanimation。
1.ViewAnimation(TweenAnimation)
ViewAnimation(TweenAnimation):
补间动画,给出两个关键帧,通过一些算法将给定属性值在给定的时间内在两个关键帧间渐变。
Viewanimation只能应用于View对象,而且只支持一部分属性,如支持缩放旋转而不支持背景颜色的改变。
而且对于Viewanimation,它只是改变了View对象绘制的位置,而没有改变View对象本身,比如,你有一个Button,坐标(100,100),Width:
200,Height:
50,而你有一个动画使其变为Width:
100,Height:
100,你会发现动画过程中触发按钮点击的区域仍是(100,100)-(300,150)。
ViewAnimation就是一系列View形状的变换,如大小的缩放,透明度的改变,位置的改变,动画的定义既可以用代码定义也可以用XML定义,当然,建议用XML定义。
可以给一个View同时设置多个动画,比如从透明至不透明的淡入效果,与从小到大的放大效果,这些动画可以同时进行,也可以在一个完成之后开始另一个。
用XML定义的动画放在/res/anim/文件夹内,XML文件的根元素可以为
默认情况下,所有动画是同时进行的,可以通过startOffset属性设置各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。
可以通过设置interpolator属性改变动画渐变的方式,如AccelerateInterpolator,开始时慢,然后逐渐加快。
默认为AccelerateDecelerateInterpolator。
定义好动画的XML文件后,可以通过类似下面的代码对指定View应用动画。
ImageViewspaceshipImage=(ImageView)findViewById(R.id.spaceshipImage);
AnimationhyperspaceJumpAnimation=AnimationUtils.loadAnimation(this,R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);
2.DrawableAnimation(FrameAnimation)
DrawableAnimation(FrameAnimation):
帧动画,就像GIF图片,通过一系列Drawable依次显示来模拟动画的效果。
在XML中的定义方式如下:
1
android=" 2 android: oneshot="true"> 3 drawable="@drawable/rocket_thrust1" android: duration="200" /> 4 5 drawable="@drawable/rocket_thrust2" android: duration="200" /> 6 drawable="@drawable/rocket_thrust3" android: duration="200" /> 7
必须以
XML文件要放在/res/drawable/目录下。
示例:
protectedvoidonCreate(BundlesavedInstanceState){
//TODOAuto-generatedmethodstubsuper.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView=(ImageView)findViewById(R.id.imageView1);
imageView.setBackgroundResource(R.drawable.drawable_anim);
anim=(AnimationDrawable)imageView.getBackground();
}
publicbooleanonTouchEvent(MotionEventevent){
if(event.getAction()==MotionEvent.ACTION_DOWN){
anim.stop();
anim.start();
returntrue;
}
returnsuper.onTouchEvent(event);
}
我在实验中遇到两点问题:
1.要在代码中调用Imageview的setBackgroundResource方法,如果直接在XML布局文件中设置其src属性当触发动画时会FC。
2.在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次。
3.最后一点是SDK中提到的,不要在onCreate中调用start,因为AnimationDrawable还没有完全跟Window相关联,如果想要界面显示时就开始动画的话,可以在onWindowFoucsChanged()中调用start()。
3.PropertyAnimation
属性动画,这个是在Android3.0中才引进的,以前学WPF时里面的动画机制好像就是这个,它更改的是对象的实际属性,在ViewAnimation(TweenAnimation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用动画时的区域,其位置与大小都不变。
而在PropertyAnimation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。
而且PropertyAnimation不止可以应用于View,还可以应用于任何对象。
PropertyAnimation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。
在PropertyAnimation中,可以对动画应用以下属性:
∙Duration:
动画的持续时间
∙TimeInterpolation:
属性值的计算方式,如先快后慢
∙TypeEvaluator:
根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值
∙RepeatCountryandbehavoir:
重复次数与方式,如播放3次、5次、无限循环,可以此动画一直重复,或播放完时再反向播放
∙Animationsets:
动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移
∙Framerefreashdelay:
多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最终刷新时间还受系统进程调度与硬件的影响
3.1PropertyAnimation的工作方式
对于下图的动画,这个对象的X坐标在40ms内从0移动到40pixel.按默认的10ms刷新一次,这个对象会移动4次,每次移动40/4=10pixel。
也可以改变属性值的改变方法,即设置不同的interpolation,在下图中运动速度先逐渐增大再逐渐减小
下图显示了与上述动画相关的关键对象
ValueAnimator即表示一个动画,包含动画的开始值,结束值,持续时间等属性。
ValueAnimator封装了一个TimeInterpolator,TimeInterpolator定义了属性值在开始值与结束值之间的插值方法。
ValueAnimator还封装了一个TypeAnimator,根据开始、结束值与TimeIniterpolator计算得到的值计算出属性值。
ValueAnimator根据动画已进行的时间跟动画总时间(duration)的比计算出一个时间因子(0~1),然后根据TimeInterpolator计算出另一个因子,最后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,计算方法为:
publicFloatevaluate(floatfraction,NumberstartValue,NumberendValue){
floatstartFloat=startValue.floatValue();
returnstartFloat+fraction*(endValue.floatValue()-startFloat);
}
参数分别为上一步的插值因子,开始值与结束值。
3.2ValueAnimator
ValueAnimator包含PropertyAnimation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。
应用PropertyAnimation有两个步聚:
1.计算属性值
2.根据属性值执行相应的动作,如改变对象的某一属性。
ValuAnimiator只完成了第一步工作,如果要完成第二步,需要实现ValueAnimator.onUpdateListener接口,如:
ValueAnimatoranimation=ValueAnimator.ofFloat(0f,1f);
animation.setDuration(1000);
animation.addUpdateListener(newAnimatorUpdateListener(){
@Override
publicvoidonAnimationUpdate(ValueAnimatoranimation){
Log.i("update",((Float)animation.getAnimatedValue()).toString());
}
});
animation.setInterpolator(newCycleInterpolator(3));
animation.start();
此示例中只是向Logcat输出了一些信息,可以改为想做的工作。
Animator.AnimatorListener
onAnimationStart()
onAnimationEnd()
onAnimationRepeat()
onAnimationCancel
ValueAnimator.AnimatorUpdateListener
onAnimationUpdate() //通过监听这个事件在属性的值更新时执行相应的操作,对于ValueAnimator一般要监听此事件执行相应的动作,不然Animation没意义(可用于计时),在ObjectAnimator(继承自ValueAnimator)中会自动更新属性,如无必要不必监听。
在函数中会传递一个ValueAnimator参数,通过此参数的getAnimatedValue()取得当前动画属性值。
可以继承AnimatorListenerAdapter而不是实现AnimatorListener接口来简化操作,这个类对AnimatorListener中的函数都定义了一个空函数体,这样我们就只用定义想监听的事件而不用实现每个函数却只定义一空函数体。
ObjectAnimatoroa=ObjectAnimator.ofFloat(tv,"alpha",0f,1f);
oa.setDuration(3000);
oa.addListener(newAnimatorListenerAdapter(){
publicvoidonAnimationEnd(Animatoranimation){
Log.i("Animation","end");
}
});
oa.start();
3.3ObjectAnimator
继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了PropertyAnimation的全部两步操作。
实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,应该满足以下条件:
∙对象应该有一个setter函数:
set
∙如上面的例子中,像ofFloat之类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果values…参数只设置了一个值的话,那么会假定为目的值,属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的getter方法:
get
∙如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。
如果上述条件不满足,则不能用ObjectAnimator,应用ValueAnimator代替。
tv=(TextView)findViewById(R.id.textview1);
btn=(Button)findViewById(R.id.button1);
btn.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
ObjectAnimatoroa=ObjectAnimator.ofFloat(tv,"alpha",0f,1f);
oa.setDuration(3000);
oa.start();
}
});
把一个TextView的透明度在3秒内从0变至1。
根据应用动画的对象或属性的不同,可能需要在onAnimationUpdate函数中调用invalidate()函数刷新视图。
3.4通过AnimationSet应用多个动画
AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。
以下例子同时应用5个动画:
1.播放anim1;
2.同时播放anim2,anim3,anim4;
3.播放anim5。
1
AnimatorSetbouncer= new AnimatorSet();
2
bouncer.play(anim1).before(anim2);
3
bouncer.play(anim2).with(anim3);
4
bouncer.play(anim2).with(anim4)
5
bouncer.play(anim5).after(amin2);
6
animatorSet.start();
3.5TypeEvalutors
根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值,android提供了以下几个evalutor:
∙IntEvaluator:
属性的值类型为int;
∙FloatEvaluator:
属性的值类型为float;
∙ArgbEvaluator:
属性的值类型为十六进制颜色值;
∙TypeEvaluator:
一个接口,可以通过实现该接口自定义Evaluator。
自定义TypeEvalutor很简单,只需要实现一个方法,如FloatEvalutor的定义:
1
public class FloatEvaluator implements TypeEvaluator{
2
public Objectevaluate(float fraction,ObjectstartValue,ObjectendValue){
3
float startFloat=((Number)startValue).floatValue();
4
return startFloat+fraction*(((Number)endValue).floatValue()-startFloat);
5
}
6
}
根据动画执行的时间跟应用的Interplator,会计算出一个0~1之间的因子,即evalute函数中的fraction参数,通过上述FloatEvaluator应该很好看出其意思。
3.6TimeInterplator
timeinterplator定义了属性值变化的方式,如线性均匀改变,开始慢然后逐渐快等。
在PropertyAnimation中是TimeInterplator,在ViewAnimation中是Interplator,这两个是一样的,在3.0之前只有Interplator,3.0之后实现代码转移至了TimeInterplator。
Interplator继承自TimeInterplator,内部没有任何其他代码。
∙AccelerateInterpolator 加速,开始时慢中间加速
∙DecelerateInterpolator 减速,开始时快然后减速
∙AccelerateDecelerateInterolator 先加速后减速,开始结束时慢,中间加速
∙AnticipateInterpolator 反向,先向相反方向改变一段再加速播放
∙AnticipateOvershootInterpolator 反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
∙BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
∙CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:
Math.sin(2*mCycles*Math.PI*input)
∙LinearInterpolator 线性,线性均匀改变
∙OvershottInterpolator 超越,最后超出目的值然后缓慢改变到目的值
∙TimeInterpolator 一个接口,允许你自定义interpolator,以上几个都是实现了这个接口
3.7当Layout改变时应用动画
ViewGroup中的子元素可以通过setVisibility使其Visible、Invisible或Gone,当有子元素可见性改变时,可以向其应用动画,通过LayoutTransition类应用此类动画:
transition.setAnimator(LayoutTransition.DISAPPEARING,customDisappearingAnim);
通过setAnimator应用动画,第一个参数表示应用的情境,可以以下4种类型:
∙APPEARING 当一个元素变为Visible时对其应用的动画
∙CHANGE_APPEARING 当一个元素变为Visible时,因系统要重新布局有一些元素需要移动,这些要移动的元素应用的动画
∙DISAPPEARING 当一个元素变为InVisible时对其应用的动画
∙CHANGE_DISAPPEARING 当一个元素变为Gone时,因系统要重新布局有一些元素需要移动,这些要移动的元素应用的动画 disappearingfromthecontainer.
第二个参数为一Animator。
mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING,30);
此函数设置动画持续时间,参数分别为类型与时间。
3.8Keyframes
keyFrame是一个时间/值对,通过它可以定义一个在特定时间的特定状态,而且在两个keyFrame之间可以定义不同的Interpolator,就相当多个动画的拼接,第一个动画的结束点是第二个动画的开始点。
KeyFrame是抽象类,要通过ofInt(),ofFloat(),ofObject()获得适当的KeyFrame,然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象,如以下例子:
Keyframekf0=Keyframe.ofInt(0,400);
Keyframekf1=Keyframe.ofInt(0.25f,200);
Keyframekf2=Keyframe.ofInt(0.5f,400);
Keyframekf4=Keyframe.ofInt(0.75f,100);
Keyframekf3=Keyframe.ofInt(1f,500);
PropertyValuesHolderpvhRotation=PropertyValuesHolder.ofKeyframe("width",kf0,kf1,kf2,kf4,kf3);
ObjectAnimatorrotationAnim=ObjectAnimator.ofPropertyValuesHolder(btn2,pvhRotation);
rotationAnim.setDuration(2000);
上述代码的意思为:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- android 30 以后3种动画 以后 动画