盒子
盒子
文章目录
  1. View动画
    1. 自定义View动画
  2. 逐帧动画
  3. 属性动画
    1. 插值器
    2. 估值器

探索Android动画

View动画

View动画包含四种动画效果,分别为平移,缩放,旋转和透明,分别对应以下Animation 的子类:

  • TranslateAnimation
    1. android:fromXDelta

      表示x的起始值,为float类型

    2. android:toXDelta

      表示x的结束值,为float类型

    3. android:fromYDelta

    4. android:toYDelta

    1
    2
    3
    4
    5
    6
    7
    <translate
    android:fromXDelta="0dp"
    android:fromYDelta="0dp"
    android:toXDelta="100dp"
    android:toYDelta="100dp"
    android:duration="800"
    android:interpolator="@android:anim/linear_interpolator"/>

    interpolator为插值器

  • ScaleAnimation
  • 该类用于缩放View

    1
    2
    3
    4
    5
    6
    7
    <scale
    android:fromXScale="0.5"
    android:fromYScale="0.5"
    android:toXScale="1.5"
    android:toYScale="1.5"
    android:pivotX="10"
    android:pivotY="10"/>

    pivotX:被缩放点的X坐标,为float类型

  • RotateAnimation
  • 用于旋转View

    1
    2
    3
    4
    5
    <rotate
    android:fromDegrees="0"
    android:toDegrees="180"
    android:pivotX="10"
    android:pivotY="10"/>

    无论是旋转动画还是缩放动画,其轴点默认都在View的中心点

  • AlphaAnimation
  • 动态透明度动画

    1
    2
    3
    <alpha
    android:fromAlpha="0.1"
    android:toAlpha="1" />

    自定义View动画

    Animation中有两个方法,分别是initaliz和applyTransformation,可在initaliz中完成初始化工作,而自定义动画步骤主要在applyTransformation完成

    1
    protected void applyTransformation(float interpolatedTime, Transformation t) {}
    1. Transformation

      一个动画在某个时间点的变换,可通过getMatrix()方法获取该时间点的Matrix

    2. Matrix

      Matrix类包含一个3x3矩阵,用于转换坐标

    3. Camara

      可用于计算3D变换并生成可用的的矩阵,如Canvas

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    public class CustomViewAnimation extends Animation {
    private Camera camera;
    private float centerX;
    private float centerY;
    private float fromDegree;
    private float toDegree;
    private float depthZ;
    private boolean reserve;
    private static final String TAG="CustomViewAnimation_LOG";
    public CustomViewAnimation(float centerX,float centerY,float fromDegree,float toDegree,float depthZ,boolean reserve){
    this.centerX=centerX;
    this.centerY=centerY;
    this.fromDegree=fromDegree;
    this.toDegree=toDegree;
    this.depthZ=depthZ;
    this.reserve=reserve;
    }
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
    camera=new Camera();
    }
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
    super.applyTransformation(interpolatedTime, t);
    float degree=fromDegree+(toDegree-fromDegree)*interpolatedTime;
    Matrix matrix=t.getMatrix();
    camera.save();
    Log.d(TAG,"interpolatedTime:"+interpolatedTime);
    if(reserve){
    camera.translate(0.0f,0.0f,depthZ*interpolatedTime);
    }else{
    camera.translate(0.0f,0.0f,depthZ*(1.0f-interpolatedTime));
    }
    camera.rotateY(degree);
    camera.getMatrix(matrix);
    camera.restore();
    matrix.preTranslate(centerY,-centerY);
    matrix.postTranslate(centerY,centerY);
    }
    }

    以上自定义View动画是通过Camera和Matrix实现了3D旋转效果,通过Transformation对象获取每一个时间点的Matrix,再计算每个时间点的旋转距离,reserve决定了是想z的负方向移动还是正方向移动

    启动View动画:

    1
    2
    3
    4
    5
    Animation animation=AnimationUtils.loadAnimation(this,R.anim.animation_test);
    view.startAnimation(animation);
    //or
    AlphaAnimation alpha=new AlphaAnimation(0.0f,1.0f);
    view.startAnimation(alpha);

    AnimationUtils

    逐帧动画

    通过Xml实现:

    res -> drawable:

    1
    2
    3
    4
    5
    <?xml version="1.0" encoding="utf-8"?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/test_first" android:duration="1000"/>
    <item android:drawable="@drawable/test_second" android:duration="1000"/>
    </animation-list>

    通过java代码实现:

    1
    2
    3
    AnimationDrawable animationDrawable=new AnimationDrawable();
    Drawable drawable=getResources().getDrawable(R.id.test_drawable,null);
    animationDrawable.addFrame(drawable,2000);

    属性动画

    属性动画与View动画不同,其动画对象可以是任何物体,且是通过改变属性来实现动画效果,所以并不像View动画仅仅是视觉上的动画

    属性动画出现在 Android 3.0(API 11),所以对于API 11以下的系统需要做适配

    属性动画主要有两个实现类:

  • ObjectAnimatior
  • ValueAnimator
  • 这两个类的不同之处在于ValueAnimator在开启动画后,会以动画的形式产生新的属性值(但不会自动将更改的属性值赋值到对象上),所以需要用户调用监听方法,根据新产生的属性值进行手动赋值。而ObjectAnimatior是对ValueAnimator做了封装,可实现自动更新属性。

    除了以上两个类,还有以下常用的方法:

  • ofInt
  • ofObject
  • setDuration
  • setRepeatCount
  • setRepeatMode
  • setElivator
  • setInterpolator
  • start
  • 以上几个方法都可在前面介绍的两个类中找到。

    setDuration,setRepeatCount,setRepeatMode分别用于设置间隔时间,设置重复播放次数,设置重复播放模式

    而of…则创建了一个ValueAnimator(ObjectAnimator)对象:

    1
    2
    public static ValueAnimator ofInt (int... values)
    public static ValueAnimator ofFloat (float... values)

    setElivator,setInterpolator分别是用于设置估值器和插值器:

    插值器

    TimeInterpolator可实现根据时间流逝的百分比计算对象属性改变的百分比

    SDK自带的插值器有:

    1
    AccelerateDecelerateInterpolator, AccelerateInterpolator, AnticipateInterpolator, AnticipateOvershootInterpolator, BaseInterpolator, BounceInterpolator, CycleInterpolator, DecelerateInterpolator, Interpolator, LinearInterpolator, OvershootInterpolator, PathInterpolator

    eg,AccelerateDecelerateInterpolator会在开始和结束时缓慢而在中间加速

    可通过实现TimeInterpolator类中的getInterpolation方法来自定义插值器

    1
    abstract float getInterpolation(float input)

    例如AccelerateDecelerateInterpolato插值器中的源码:

    1
    2
    3
    public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }

    估值器

    TypeElivator指的是类型估值算法,它可实现根据动画对象当前属性改变的百分比计算改变后的属性值

    SDK默认的估值器有:

    1
    ArgbEvaluator, FloatArrayEvaluator, FloatEvaluator, IntArrayEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator

    可通过实现TypeElivator类中的抽象方法evaluate来自定义估值器

    1
    abstract T evaluate(float fraction, T startValue, T endValue)

    如IntEvaluator估值器:

    1
    2
    3
    4
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
    int startInt = startValue;
    return (int)(startInt + fraction * (endValue - startInt));
    }

    通过插值器计算出对象属性改变的百分比提供给估值器计算最新的属性值

    支持一下
    扫一扫,支持Grooter
    • 微信扫一扫
    • 支付宝扫一扫