安卓三种动画小结

来源:互联网 发布:esp8266与单片机连接 编辑:程序博客网 时间:2024/05/18 02:52

安卓中,动画可以分为三类。逐帧动画,补间动画,属性动画。稍微小结下,我对这三个动画的认识。

逐帧动画

AnimationDrawble,所以逐帧动画,其实是一种图像。通过设置ImageView类的background好或者src从代码和xml两个方式上载入。

纯代码
AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();frameAnimation.start();
xml定义
<animation-list android:id="@+id/selected"  android:oneshot="false"><item android:drawable="@drawable/  wheel0" android:duration="50" /><item android:drawable="@drawable/wheel1" android:duration="50" /><item android:drawable="@drawable/wheel2" android:duration="50" /></animation-list>

补间动画

补间:开发者只需要给出动画的起始和结束帧状态,中间的帧交由安卓系统计算和补齐。抽象类Animation是补间动画的基类。同样可以分为xml和纯代码两种方式显示。补间动画无法实现动画无限重复播放。

涉及的API

AlphaAnimation,ScaleAnimation,RotateAnimation,TranslateAnimation,AnimationSet,Interpolator(差值接口),TimeInterpolator,Transformation,Camera(三维图形变换,类似Matrix)

Animation animation = AnimationUtils.loadAnimation(Context context,int id)

实现自定义补间动画

继承Animation,重写initalize()方法和applyTransformation(float interpolatedTime,Transformation t)方法

  • interpolatedTime:代表了动画的时间进行比,不管动画实际的持续时间如何,当动画播放时,该参数总是自动从0变化到1.
  • Transformation 该参数代表了补间动画在不同时刻对图形或组件的变形程度。
applyTransformation方法的参考代码:
camera.save();camera.rotateY(360 *interpolatedTime);Matrix matrix = transformation.getMatrix();camera.getMatrix(matrix);matrix.preTranslate(-centerX,-centerY);camera.restore();

属性动画

属性动画主要有两方面组成:1计算各帧的相关属性值 2为指定对象设置这些计算后的值。
对象的属性名称有:rotationX,rotationY,scaleX,scaleY,alpha,translationX,translationY
监听事件 ValueAnimator.AnimatorUpdateListener , Animator.AnimatorListener

涉及的API
Animator:属性动画的基类。
  • ValueAnimator: 负责第一方面的内容。因此第二方面,为指定对象设置属性值须由程序员通过监听来完成。
  • ObjectAnimator,是ValueAnimator的子类,使用起来更简单。
  • AnimatorSet(属性动画组合),它是Animator的子类,用于组合多个Animator,指定播放顺序。
Evaluator 计算器,控制属性动画如何计算属性值.TypeEvaluator 计算器接口,通过实现该接口来实现自定义计算器。
  • IntEvaluator
  • FloatEvaluator
  • ArgbEvaluator
  • PointFEvaluator
  • RectEvaluator
ValueAnimator的使用
基本用法
  • 调用ValueAnimator的ofInt(),ofFloat()或ofObject静态方法创建
  • 设置持续时间,插值方式,动画模式等属性
  • 注册监听器AnimationUpdateListerner,在监听方法里,通过getAnimatedValue()方法,把当前帧的值应用到所需要的对象上。
  • start()启动动画
如果getAnimatedValue()返回的不是系统默认的值,借助TypeEvaluator接口,用系统自带的实现类,如PointFEvaluator,FloatArrayEvaluator,或者自己实现TypeEvaluetor,重写evaluator方法。
代码如下:
valueAnimator.setObjectValues(new PointF(0, 0));valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {    @Override    public PointF evaluate(float fraction, PointF startValue, PointF endValue) {        Log.e("evaluate","fraction="+fraction + " startValue="+startValue +" endValue=" + endValue);        PointF pointF = new PointF();        pointF.x = 200 * fraction * 3;        pointF.y = (float) (0.5 * 10 * 200 * fraction * fraction);        return pointF;    }});valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {            PointF pointF = (PointF) animation.getAnimatedValue();            ball.setTranslationX(pointF.x);            ball.setTranslationY(pointF.y);        }    });
ObjectAnimator的使用

继承自ValueAnimator,完成了属性动画的两个方面,所以可以直接把动画应用到对象上。

注意事项
  • 该对象存在对应属性的setter方法。
  • 如果只提供一个值,则该值被认为是结束值,此时需要提供getter方法。
  • 如果该对象的setter方法不会自动调用invalidate()方法,则需要在onAnimationUpdate()监听方法里调用invalidate()刷新屏幕。
xml定义属性动画
<set xmlns:android="http://schemas.android.com/apk/res/android"><objectAnimator    android:duration="600"    android:interpolator="@android:interpolator/accelerate_decelerate"    android:propertyName="alpha"    android:repeatCount="infinite"    android:repeatMode="reverse"    android:valueFrom="1"    android:valueTo="0"    android:valueType="floatType"    />Animator animator = AnimatorInflator.loadAnimator(Context context,int resId);

多个属性动画同时播放的实现
1、通过AnimatorSet
AnimatorSet s = new Animatorset();s.play(animator1).before(animator2);s.paly(animator2).befor(animator3);
2、 ValueAnimator,ObjectAnimater的AnimatorUpdateListener监听方法onAnimationUpdate里,调用对象的多个属性setter即可。
3、借助PropertyValuesHolder
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha",1f,0f);PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX",1f,0f);PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f);ObjectAnimator animator1 = ObjectAnimator.ofPropertyValuesHolder(txt,holder1, holder2, holder3);animator1.setDuration(800);animator1.setInterpolator(new AccelerateDecelerateInterpolator());animator1.setRepeatMode(ValueAnimator.REVERSE);animator1.setRepeatCount(ValueAnimator.INFINITE);animator1.setStartDelay(1000);animator1.start();
借助ViewPropertyAnimator实现同时播放动画
//need API12      mBlueBall.animate()//              .alpha(0)//              .y(mScreenHeight / 2).setDuration(1000)              // need API 12              .withStartAction(new Runnable()              {                  @Override                  public void run()                  {                      Log.e(TAG, "START");                  }                  // need API 16              }).withEndAction(new Runnable()              {                  @Override                  public void run()                  {                      Log.e(TAG, "END");                      runOnUiThread(new Runnable()                      {                          @Override                          public void run()                          {                              mBlueBall.setY(0);                              mBlueBall.setAlpha(1.0f);                          }                      });                  }              }).start(); 
等效于:
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,          0f, 1f);  PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 0,          mScreenHeight / 2, 0);  ObjectAnimator.ofPropertyValuesHolder(mBlueBall, pvhX, pvhY).setDuration(1000).start();

p.s. 参考《疯狂安卓讲义》
Android 属性动画(Property Animation) 完全解析 (下)

0 0
原创粉丝点击