android两种动画模式

  3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中又引入了一个新的动画系统:property animation,这三种动画模式在SDK中被称为property animation,view animation,drawable animation。 

1. View Animation(Tween Animation)

  View Animation(Tween Animation):补间动画,给出两个关键帧,通过一些算法将给定属性值在给定的时间内在两个关键帧间渐变。

  View animation只能应用于View对象,而且只支持一部分属性,如支持缩放旋转而不支持背景颜色的改变。

  而且对于View animation,它只是改变了View对象绘制的位置,而没有改变View对象本身,比如,你有一个Button,坐标 (100,100),Width:200,Height:50,而你有一个动画使其变为Width:100,Height:100,你会发现动画过程中触 发按钮点击的区域仍是(100,100)-(300,150)。

  View Animation就是一系列View形状的变换,如大小的缩放,透明度的改变,位置的改变,动画的定义既可以用代码定义也可以用XML定义,当然,建议用XML定义。

  可以给一个View同时设置多个动画,比如从透明至不透明的淡入效果,与从小到大的放大效果,这些动画可以同时进行,也可以在一个完成之后开始另一个。

  用XML定义的动画放在/res/anim/文件夹内,XML文件的根元素可以 为<alpha>,<scale>,<translate>,<rotate>,interpolator 元素或<set>(表示以上几个动画的集合,set可以嵌套)。默认情况下,所有动画是同时进行的,可以通过startOffset属性设置 各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。

  可以通过设置interpolator属性改变动画渐变的方式,如AccelerateInterpolator,开始时慢,然后逐渐加快。默认为AccelerateDecelerateInterpolator。

  定义好动画的XML文件后,可以通过类似下面的代码对指定View应用动画。

ImageView spaceshipImage = (ImageView)findViewById(R.id.spaceshipImage);Animation hyperspaceJumpAnimation=AnimationUtils.loadAnimation( this, R.anim.hyperspace_jump);spaceshipImage.startAnimation(hyperspaceJumpAnimation);

2. Drawable Animation(Frame Animation)

  Drawable Animation(Frame Animation):帧动画,就像GIF图片,通过一系列Drawable依次显示来模拟动画的效果。在XML中的定义方式如下:

?
1
2
3
4
5
6
< animation-list xmlns:android = "http://schemas.android.com/apk/res/android"
     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" />
</ animation-list >

  必须以<animation-list>为根元素,以<item>表示要轮换显示的图片,duration属性表示各项显示的时间。XML文件要放在/res/drawable/目录下。示例:

protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.main); imageView = (ImageView) findViewById(R.id.imageView1); imageView.setBackgroundResource(R.drawable.drawable_anim); anim = (AnimationDrawable) imageView.getBackground(); } public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { anim.stop(); anim.start(); return true; } return super.onTouchEvent(event); }

  我在实验中遇到两点问题:

  1. 要在代码中调用Imageview的setBackgroundResource方法,如果直接在XML布局文件中设置其src属性当触发动画时会FC。
  2. 在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次。
  3. 最后一点是SDK中提到的,不要在onCreate中调用start,因为AnimationDrawable还没有完全跟Window相关联,如果想要界面显示时就开始动画的话,可以在onWindowFoucsChanged()中调用start()。

3. Property Animation

  属性动画,这个是在Android 3.0中才引进的,以前学WPF时里面的动画机制好像就是这个,它更改的是对象的实际属性,在View Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的 有效点击区域还是没有应用动画时的区域,其位置与大小都不变。而在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。

在Property Animation中,可以对动画应用以下属性:

  • Duration:动画的持续时间
  • TimeInterpolation:属性值的计算方式,如先快后慢
  • TypeEvaluator:根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值
  • Repeat Country and behavoir:重复次数与方式,如播放3次、5次、无限循环,可以此动画一直重复,或播放完时再反向播放
  • Animation sets:动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移
  • Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最终刷新时间还受系统进程调度与硬件的影响

3.1 Property Animation的工作方式

  对于下图的动画,这个对象的X坐标在40ms内从0移动到40 pixel.按默认的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,计算方法为 :

public Float evaluate( float fraction, Number startValue, Number endValue) { float startFloat = startValue.floatValue(); return startFloat + fraction * (endValue.floatValue() - startFloat); }

参数分别为上一步的插值因子,开始值与结束值。

3.2 ValueAnimator

  ValueAnimator包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。应用Property Animation有两个步聚:

  1. 计算属性值
  2. 根据属性值执行相应的动作,如改变对象的某一属性。

  ValuAnimiator只完成了第一步工作,如果要完成第二步,需要实现ValueAnimator.onUpdateListener接口,如:

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();

此示例中只是向Logcat输出了一些信息,可以改为想做的工作。

Animator.AnimatorListener

onAnimationStart()onAnimationEnd()onAnimationRepeat()onAnimationCancel

ValueAnimator.AnimatorUpdateListener

onAnimationUpdate()   // 通过监听这个事件在属性的值更新时执行相应的操作,对于ValueAnimator一般要监听此事件执行相应的动作,不然Animation没意义(可用于计时),在ObjectAnimator(继承自ValueAnimator)中会自动更新属性,如无必要不必监听。在函数中会传递一个ValueAnimator参数,通过此参数的getAnimatedValue()取得当前动画属性值。

  可以继承AnimatorListenerAdapter而不是实现AnimatorListener接口来简化操作,这个类对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();

3.3 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()函数刷新视图。

3.4 通过AnimationSet应用多个动画

  AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。

  以下例子同时应用5个动画:

  1. 播放anim1;
  2. 同时播放anim2,anim3,anim4;
  3. 播放anim5。
?
1
2
3
4
5
6
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();

3.5 TypeEvalutors

  根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值,android提供了以下几个evalutor:

  • IntEvaluator:属性的值类型为int;
  • FloatEvaluator:属性的值类型为float;
  • ArgbEvaluator:属性的值类型为十六进制颜色值;
  • TypeEvaluator:一个接口,可以通过实现该接口自定义Evaluator。

  自定义TypeEvalutor很简单,只需要实现一个方法,如FloatEvalutor的定义:

?
1
2
3
4
5
6
public class FloatEvaluator implements TypeEvaluator {
     public Object evaluate( float fraction, Object startValue, Object endValue) {
         float startFloat = ((Number) startValue).floatValue();
         return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
     }
}

  根据动画执行的时间跟应用的Interplator,会计算出一个0~1之间的因子,即evalute函数中的fraction参数,通过上述FloatEvaluator应该很好看出其意思。

3.6 TimeInterplator

  time interplator定义了属性值变化的方式,如线性均匀改变,开始慢然后逐渐快等。在Property Animation中是TimeInterplator,在View Animation中是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时,因系统要重新布局有一些元素需要移动,这些要移动的元素应用的动画 disappearing from the container.

  第二个参数为一Animator。

mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);

  此函数设置动画持续时间,参数分别为类型与时间。

3.8 Keyframes

  keyFrame是一个 时间/值 对,通过它可以定义一个在特定时间的特定状态,而且在两个keyFrame之间可以定义不同的Interpolator,就相当多个动画的拼接,第一个动 画的结束点是第二个动画的开始点。KeyFrame是抽象类,要通过ofInt(),ofFloat(),ofObject()获得适当的 KeyFrame,然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象,如以下 例子:

Keyframe kf0 = Keyframe.ofInt(0, 400);Keyframe kf1 = Keyframe.ofInt(0.25f, 200);Keyframe kf2 = Keyframe.ofInt(0.5f, 400);Keyframe kf4 = Keyframe.ofInt(0.75f, 100);Keyframe kf3 = Keyframe.ofInt(1f, 500);PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf4, kf3);ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(btn2, pvhRotation);rotationAnim.setDuration(2000);

  上述代码的意思为:设置btn对象的width属性值使其:

  • 开始时 Width=400
  • 动画开始1/4时 Width=200
  • 动画开始1/2时 Width=400
  • 动画开始3/4时 Width=100
  • 动画结束时 Width=500
  第一个参数为时间百分比,第二个参数是在第一个参数的时间时的属性值。
  定义了一些Keyframe后,通过PropertyValuesHolder类的方法ofKeyframe封装,然后通过ObjectAnimator.ofPropertyValuesHolder获得Animator。
  用下面的代码可以实现同样的效果:
ObjectAnimator oa=ObjectAnimator.ofInt(btn2, "width", 400,200,400,100,500);oa.setDuration(2000);oa.start();

3.9 Animating Views

  在View Animation中,对View应用Animation并没有改变View的属性,动画的实现是通过其Parent View实现的,在View被drawn时Parents View改变它的绘制参数,draw后再改变参数invalidate,这样虽然View的大小或旋转角度等改变了,但View的实际属性没变,所以有效 区域还是应用动画之前的区域,比如你把一按钮放大两倍,但还是放大这前的区域可以触发点击事件。为了改变这一点,在Android 3.0中给View增加了一些参数并对这些参数增加了相应的getter/setter函数(ObjectAnimator要用这些函数改变这些属性):

  • translationX,translationY:转换坐标(control where the View is located as a delta from its left and top coordinates which are set by its layout container.)
  • rotation,rotationX,rotationY:旋转,rotation用于2D旋转角度,3D中用到后两个
  • scaleX,scaleY:缩放
  • x,y:View的最终坐标(utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values.)
  • alpha:透明度
  跟位置有关的参数有3个,以X坐标为例,可以通过getLeft(),getX(),getTranslateX()获得,若有一Button btn2,布局时其坐标为(40,0):
// 应用动画之前 btn2.getLeft(); // 40 btn2.getX(); // 40 btn2.getTranslationX(); // 0 // 应用translationX动画 ObjectAnimator oa=ObjectAnimator.ofFloat(btn2,"translationX", 200);oa.setDuration(2000);oa.start(); /* 应用translationX动画后btn2.getLeft(); //40btn2.getX(); //240btn2.getTranslationX(); //200 */ // 应用X动画,假设没有应用之前的translationX动画 ObjectAnimator oa=ObjectAnimator.ofFloat(btn2, "x", 200);oa.setDuration(2000);oa.start(); /* 应用X动画后btn2.getLeft(); //40btn2.getX(); //200btn2.getTranslationX(); //160 */
  无论怎样应用动画,原来的布局时的位置通过getLeft()获得,保持不变;
  X是View最终的位置;
  translationX为最终位置与布局时初始位置这差。
  所以若就用translationX即为在原来基础上移动多少,X为最终多少
  getX()的值为getLeft()与getTranslationX()的和
  对于X动画,源代码是这样的:
case X: info.mTranslationX = value - mView.mLeft; break;

  Property Animation也可以在XML中定义

  • <set> - AnimatorSet
  • <animator> - ValueAnimator
  • <objectAnimator> - ObjectAnimator
  XML文件应放大/res/animator/中,通过以下方式应用动画:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator);set.setTarget(myObject);set.start();

3.10 ViewPropertyAnimator

  如果需要对一个View的多个属性进行动画可以用ViewPropertyAnimator类,该类对多属性动画进行了优化,会合并一些invalidate()来减少刷新视图,该类在3.1中引入。

  以下两段代码实现同样的效果: 

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();

 

myView.animate().x(50f).y(100f);







动画类型

Androidanimation由四种类型组成

XML
alpha渐变透明度动画效果
scale渐变尺寸伸缩动画效果
translate画面转换位置移动动画效果
rotate画面转移旋转动画效果


JavaCode
AlphaAnimation渐变透明度动画效果
ScaleAnimation渐变尺寸伸缩动画效果
TranslateAnimation画面转换位置移动动画效果
RotateAnimation画面转移旋转动画效果

Android动画模式

Animation主要有两种动画模式

一种是tweened animation(渐变动画)
XMLJavaCode
alphaAlphaAnimation
scaleScaleAnimation


一种是frame by frame(画面转换动画)
XML中JavaCode
translateTranslateAnimation
rotateRotateAnimation

Android动画解析

alpha xml 淡出效果


<?xml version="1.0" encoding="utf-8"?> <set xmlns:android=" http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="500" /> </set> <!-- fromAlpha:开始时透明度 toAlpha: 结束时透明度 duration:动画持续时间 -->
alpha xml 淡入效果

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android=" http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="500" /> </set> <!-- fromAlpha:开始时透明度 toAlpha: 结束时透明度 duration:动画持续时间 -->

rotate.xml 旋转效果: 
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android=" http://schemas.android.com/apk/res/android"><rotate android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromDegrees="300" android:toDegrees="-360" android:pivotX="10%" android:pivotY="100%" android:duration="10000" /> </set> <!-- fromDegrees 动画开始时的角度 toDegrees 动画结束时物件的旋转角度,正代表顺时针 pivotX 属性为动画相对于物件的X坐标的开始位置 pivotY 属性为动画相对于物件的Y坐标的开始位置 -->

scale.xml 缩放效果: 

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android=" http://schemas.android.com/apk/res/android"> <scale android:interpolator= "@android:anim/decelerate_interpolator" android:fromXScale="0.0" android:toXScale="1.5" android:fromYScale="0.0" android:toYScale="1.5" android:pivotX="50%" android:pivotY="50%" android:startOffset="0" android:duration="10000" android:repeatCount="1" android:repeatMode="reverse" /> </set> <!-- fromXDelta,fromYDelta 起始时X,Y座标,屏幕右下角的座标是X:320,Y:480 toXDelta, toYDelta 动画结束时X,Y的座标 --> <!-- interpolator 指定动画插入器常见的有加速减速插入器 accelerate_decelerate_interpolator加速插入器 accelerate_interpolator,减速插入器 decelerate_interpolator。 fromXScale,fromYScale, 动画开始前X,Y的缩放,0.0为不显示, 1.0为正常大小toXScale,toYScale, 动画最终缩放的倍数, 1.0为正常大小,大于1.0放大pivotX, pivotY 动画起始位置,相对于屏幕的百分比,两个都为50%表示动画从屏幕中间开始 startOffset, 动画多次执行的间隔时间,如果只执行一次,执行前会暂停这段时间, 单位毫秒 duration,一次动画效果消耗的时间,单位毫秒, 值越小动画速度越快 repeatCount,动画重复的计数,动画将会执行该值+1次 repeatMode,动画重复的模式,reverse为反向,当第偶次执行时,动画方向会相反。 restart为重新执行,方向不变 -->



translate.xml 移动效果: 
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android=" http://schemas.android.com/apk/res/android"><translate android:fromXDelta="320" android:toXDelta="0" android:fromYDelta="480" android:toYDelta="0" android:duration="10000" /> </set> <!-- fromXDelta,fromYDelta 起始时X,Y座标,屏幕右下角的座标是X:320,Y:480 toXDelta, toYDelta 动画结束时X,Y的座标 -->  





#################################################



Andriod 的Animations可以从形式上分为两大类,分别是 Tweened Animations 和Frame-By-Frame Animations。Tweened Animations可以理解为补间动画,也就是某一张图或者其他对象,进行旋转、变形等动画;而Frame-By-Frame Animations是多张图片或对象,进行一帧一帧的变化。简单而也,前者是本身改变的动画,后者是与其他内容的交替显示形成的动画。

Tweened Animations有4种样式,分别为Alpha,Rotate,Translate,Scale。分别表示渐变,旋转,位移,缩放。要实现以上4种动画,必须要给出每种动画的需要参数。
Alpha:因为是渐变,所以需要给出改变之前的透明度,改变之后的透明度,总共改变的时间。
Rotate:旋转,必定要知道旋转的圆心在哪边,所以要定义圆心的X与Y轴,以及转动的时间,转动的角度等。
Translate:位移,即要知道原来对象的XY轴和改变后的XY轴,以及运动的时间等。
Scale:缩放,首先要知道XY轴缩放的比率,以及缩放前后中心坐标的变化,当然还有缩放的时间。
使用Animation还需要知道一些知识点:
Interpolator:它定义了动画的速率,它有若干子类,AccelerateDecelerateInterpolator是两头慢,中间快的动画效果, AccelerateInterpolator是加速的动画效果,DecelerateInterpolator是减速动画效果, LinearInterpolator是匀速动画效果,等等。这些加速效果可以根据实际的需求来使用。
AnimationSet:它是Animation的一个集合,可以将定义好的各个动画,放入AnimationSet集合中,然后再进行对集合的设置,控制集合内的动画如何运行。

Tweened Animations的实现

Tweened Animations实现有两种方式,一种为在Java代码中设置,另一种为在XML文件中设置。两种方式各有优劣,下面一一介绍。

Tweened Animations的第一种实现:

我们的例子是Activity上有4个按钮和一张图片,4个按钮分别代表上面的四种动画效果。
布局文件很简单,就是4个按钮和一张图片的定义设置,在此略去,附件中可见详情。
在Java代码中,我们为每个按钮绑定了监听器。
Alpha监听器:
  1. class AlphaOnClickListener implements OnClickListener{

  2. @Override

  3. publicvoid onClick(View arg0) {

  4. // TODO Auto-generated method stub

  5. AnimationSet animationSet = new AnimationSet(true);//创建一个Animation的集合,这里构造函数的参数是个boolean值,他表示的是这个AnimationSet中是否共享一个Interpolator,也就是在这个集合内不同的动画是否以同样地速率变化,如果为false,那么下面需要对每一个动画进行Interpolator的设置。

  6. AlphaAnimation alphaAnimation = new AlphaAnimation(1,0);//设置从不透明到透明,这里两个参数的取值为0~1,0表示完全透明,1表示完全不透明

  7. alphaAnimation.setDuration(2000);//设置动画的时间为2秒

  8. animationSet.addAnimation(alphaAnimation);//将创建的alphaAnimation加入Animation集合中

  9. item.startAnimation(animationSet);//在ImageView上设置动画

  10. }

  11. }

Rotate监听器:
  1. class RotateOnClickListener implements OnClickListener{

  2. @Override

  3. publicvoid onClick(View arg0) {

  4. // TODO Auto-generated method stub

  5. AnimationSet animationSet = new AnimationSet(true);//同上

  6. RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

  7. //RotateAnimation有6个参数

  8. //1.初始的角度

  9. //2.旋转的角度,可以为负的,即为逆时针转

  10. //3.转的圆心的X坐标是相对谁为参照物的,这里有3种情况:RELATIVE_TO_SELF,RELATIVE_TO_PARENT,ABSOLUTE,分别是相对自己,相对父控件,绝对位置

  11. //4.具体的X坐标,与第三个参数有关,若第3个参数是Animation.RELATIVE_TO_SELF,第四个参数是0.5f,那么圆心的X坐标就是自身控件宽度的0.5倍

  12. //5.转的圆心的Y坐标是相对谁为参照物,参数同3

  13. //6. 具体的Y坐标,与第三个参数有关,若第3个参数是Animation.RELATIVE_TO_SELF,第四个参数是0.5f,那么圆心的Y坐标就是自身控件宽度的0.5倍

  14. rotateAnimation.setDuration(2000);//设置动画的时间

  15. animationSet.addAnimation(rotateAnimation);//将创建的alphaAnimation加入Animation集合中

  16. item.startAnimation(animationSet);//在ImageView上设置动画

  17. }

  18. }

Translate监听器:

  1. class TranslateOnClickListener implements OnClickListener{

  2. @Override

  3. publicvoid onClick(View arg0) {

  4. // TODO Auto-generated method stub

  5. AnimationSet animationSet = new AnimationSet(true);//创建一个Animation的集合

  6. TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,1f);

  7. //第1,2个参数是变化之前的X坐标

  8. //第3,4个参数是变化之后的X坐标

  9. //第5,6个参数是变化之前的Y坐标

  10. //第7,8个参数是变化之后的Y坐标

  11. translateAnimation.setDuration(2000);//设置动画的时间

  12. animationSet.addAnimation(translateAnimation);//将创建的alphaAnimation加入Animation集合中

  13. item.startAnimation(animationSet);//在ImageView上设置动画

  14. }

  15. }

Scale监听器:

  1. class ScaleOnClickListener implements OnClickListener{

  2. @Override

  3. publicvoid onClick(View arg0) {

  4. // TODO Auto-generated method stub

  5. AnimationSet animationSet = new AnimationSet(true);//同上

  6. ScaleAnimation scaleAnimation = new ScaleAnimation(1, 0.1f,1,0.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

  7. //第1个参数是X的原始比率,第2个参数是X变化后的比率

  8. //第3个参数是Y的原始比率,第4个参数是Y变化后的比率

  9. //第5,6个参数是最后动画结束时的X轴坐标

  10. //第7,8个参数是最后动画结束时的Y轴坐标

  11. scaleAnimation.setDuration(2000);//设置动画的时间

  12. animationSet.addAnimation(scaleAnimation);//将创建的alphaAnimation加入Animation集合中

  13. item.startAnimation(animationSet);//在ImageView上设置动画

  14. }

  15. }

以上是Tweened Animations的基本使用,当然还有其他的设置,比如设置延迟动画可以使用对Animation或AnimationSet设置setStartOffset(long time)等。

Tweened Animations的第二种实现:

使用XML文件来对动画进行定义和设置,首先要在res目录下建立anim文件夹,在这个文件夹下面就放置一个我们定义的XML文件,而且,每个XML文件都是以如下为标签:
  1. <?xmlversion="1.0"encoding="UTF-8"?>

  2. <setxmlns:android="http://schemas.android.com/apk/res/android"

  3. android:interpolator="@android:anim/accelerate_interpolator"

  4. >

  5. </set>

我们将要定义的动画放在set标签中,里面的android:interpolator属性就是定义了这个set中的动画是以什么速率进行变化的,它的值是android自带的,可以再Android API中查到。
看一下上述4中动画的定义:
  1. <alpha

  2. android:fromAlpha="1.0"//初始透明度

  3. android:toAlpha="0.0"//结束透明度

  4. android:duration="3000"//时长

  5. ></alpha>

  6. <rotate

  7. android:fromDegrees="0"//初始旋转角度

  8. android:toDegrees="-360"//结束旋转角度,可为负,即逆时针

  9. android:duration="3000"//时长

  10. android:pivotX="50%" //下方介绍

  11. android:pivotY="50%"//下方介绍

  12. ></rotate>

  13. <scale

  14. android:fromXScale="1.0"//初始X坐标比率

  15. android:toXScale="0.1"//结束X坐标比率

  16. android:fromYScale="1.0"//初始Y坐标比率

  17. android:toYScale="0.1"//结束Y坐标比率

  18. android:pivotX="50%"//下方介绍

  19. android:pivotY="50%"//下方介绍

  20. android:duration="3000"//时长

  21. ></scale>

  22. <translate

  23. android:fromXDelta="0%"//下方介绍

  24. android:toXDelta="50%"//下方介绍

  25. android:fromYDelta="0%"//下方介绍

  26. android:toYDelta="100%"//下方介绍

  27. android:duration="3000"//时长

  28. ></translate>

我们在上面代码标注“下方介绍”的这些值,我们有三种写法,如:50,50%,50%p。这三种写法就分别代表了ABSOLUTE,RELATIVE_TO_SELF和RELATIVE_TO_PARENT。
定义完XML文件后,我们就要在Java代码中对其使用了。
举例,若将上面的Alpha的XML文件命名为alpha.xml,则如此使用:
  1. class AlphaOnClickListener implements OnClickListener{

  2. @Override

  3. publicvoid onClick(View arg0) {

  4. // TODO Auto-generated method stub

  5. Animation alphaAnimation = AnimationUtils.loadAnimation(AnimationDemo2Activity.this, R.anim.alpha);//载入alpha.xml

  6. item.startAnimation(alphaAnimation);//在ImageView上设置动画

  7. }

  8. }

也可以将多个效果放在一个文件中的一个set内,那么这几个动画会根据自己的设置一起运行,达到对同一个对象的多种效果的叠加效果。

以上是Tweened Animations的两种基本用法,Animation的使用远远不止这些,需要进一步的学习哇。

附件是Tweened Animations的两种基本用法的示例代码,仅供参考。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值