• 动画完全解析(二):补间动画原理及自定义动画


    对于补间动画原理,我们直接查看系统动画源码(部分):

    1,AlphaAnimation

    /**
    * Changes the alpha property of the supplied {@link Transformation}
    */
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
    final float alpha = mFromAlpha;
    t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
    }

    2,TranslateAnimation

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
    float dx = mFromXDelta;
    float dy = mFromYDelta;
    if (mFromXDelta != mToXDelta) {
    dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
    }
    if (mFromYDelta != mToYDelta) {
    dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
    }
    t.getMatrix().setTranslate(dx, dy);
    }

    3,ScaleAnimation

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
    float sx = 1.0f;
    float sy = 1.0f;
    float scale = getScaleFactor();

    if (mFromX != 1.0f || mToX != 1.0f) {
    sx = mFromX + ((mToX - mFromX) * interpolatedTime);
    }
    if (mFromY != 1.0f || mToY != 1.0f) {
    sy = mFromY + ((mToY - mFromY) * interpolatedTime);
    }

    if (mPivotX == 0 && mPivotY == 0) {
    t.getMatrix().setScale(sx, sy);
    } else {
    t.getMatrix().setScale(sx, sy, scale * mPivotX, scale * mPivotY);
    }
    }

    4,RotateAnimation

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
    float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
    float scale = getScaleFactor();

    if (mPivotX == 0.0f && mPivotY == 0.0f) {
    t.getMatrix().setRotate(degrees);
    } else {
    t.getMatrix().setRotate(degrees, mPivotX * scale, mPivotY * scale);
    }
    }

    由上可以看到,自定义动画的核心思想: 重写applyTransformation方法,通过t 获取变换矩阵matrix ,使用matrix 对目标对象进行相应的变换.(除透明度动画)

    以下是几个自定义动画:

    1,左右摇动动画

    package com.wytiger.customanimation.animation;

    import android.view.animation.Animation;
    import android.view.animation.Transformation;


    /**
    * 左右摇动动画
    * @author wytiger
    * @date 2016年3月16日
    */
    public class ShakeAnimation extends Animation {

    /**
    * 初始化,可以获取到目标控件及父控件的宽高
    */
    @Override
    public void initialize(int width, int height, int parentWidth,
    int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
    }


    /**
    * 具体要执行的动画效果
    * interpolatedTime: 插值时间,也就是执行的百分比
    * t: 动画的目标对象
    */
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
    super.applyTransformation(interpolatedTime, t);
    // t.setAlpha(interpolatedTime);
    //获取变换矩阵,通过变换矩阵设置目标对象平移
    t.getMatrix().setTranslate((float) (Math.sin(interpolatedTime*10)*100), 0);

    }

    }

    2,电视机关机动画

    package com.wytiger.customanimation.animation;

    import android.graphics.Matrix;
    import android.view.animation.AccelerateDecelerateInterpolator;
    import android.view.animation.Animation;
    import android.view.animation.Transformation;

    /**
    * 电视剧关闭动画
    *
    * @author wytiger
    * @date 2016年3月16日
    */
    public class TVOffAnimation extends Animation {

    private int halfWidth;

    private int halfHeight;

    @Override
    public void initialize(int width, int height, int parentWidth,
    int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
    setDuration(500);
    setFillAfter(true);
    // 保存View的中心点
    halfWidth = width / 2;
    halfHeight = height / 2;
    setInterpolator(new AccelerateDecelerateInterpolator());

    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {

    /**
    * 横向来讲前80%的时间我们要横向拉伸到150%,纵向是直接减小,最后只留一条线。
    * 后20%的时间里我们要横向从150%压缩至0%,纵向保持不变就好了,当横向为0的时候就全部消失了。
    * 可能大家对于1+0.625f*interpolatedTime, 1-interpolatedTime/0.8f+0.01f,
    * 7.5f*(1-interpolatedTime), 0.01f
    * 这4个值比较疑惑,其实很简单,这是一个一次函数的函数值, 如图为sx的变化曲线


    */

    final Matrix matrix = t.getMatrix();
    if (interpolatedTime < 0.8) {
    matrix.preScale(1 + 0.625f * interpolatedTime,
    1 - interpolatedTime / 0.8f + 0.01f, halfWidth, halfHeight);
    } else {
    matrix.preScale(7.5f * (1 - interpolatedTime), 0.01f, halfWidth,
    halfHeight);
    }
    }
    }

    3,自定义图片旋转动画

    package com.wytiger.customanimation.animation;

    import android.graphics.Camera;
    import android.graphics.Matrix;
    import android.view.animation.Animation;
    import android.view.animation.Transformation;

    /**
    * 自定义图片旋转动画
    *
    * @author wytiger
    * @date 2016年3月16日
    */
    public class ViewRotateAnimation extends Animation {

    int mCenterX;
    int mCenterY;

    /**
    * Camera就像一个摄像机,一个物体在原地不动,然后我们带着这个摄像机四处移动,
    * 在摄像机里面呈现出来的画面,就会有立体感,就可以从各个角度观看这个物体。
    */

    Camera camera = new Camera();


    public ViewRotateAnimation() {

    }

    @Override
    public void initialize(int width, int height,
    int parentWidth,int parentHeight){
    super.initialize(width, height, parentWidth, parentHeight);

    mCenterX = width / 2;
    mCenterY = height / 2;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t){

    final Matrix matrix = t.getMatrix();

    //保存状态,类似于canvas的save方法
    camera.save();

    //变换
    camera.translate(0.0f, 0.0f, (1300 - 1300.0f * interpolatedTime));
    camera.rotateY(360 * interpolatedTime);
    camera.getMatrix(matrix);
    matrix.preTranslate(-mCenterX, -mCenterY);
    matrix.postTranslate(mCenterX, mCenterY);
    //恢复状态
    camera.restore();
    }

    }

  • 相关阅读:
    OpenCv 学习安装(一)
    mysql 5.7.22安装
    sql游标
    (转)C# 获取当前路径的7中方法
    IIS 配置好了,为什么网站打开一片空白?
    (转)C#文件操作
    关于电脑开机不出现桌面即不启动explorer.exe桌面程序--------正解
    C#中 非静态字段、方法或属性“XXXX”要求对象引用-----解决方案
    关于svn获取获取文件时 Unable to connect to a repository at URL"https://..."执行上下文错误:参数错误
    获取汉字全拼、首字母缩写
  • 原文地址:https://www.cnblogs.com/wytiger/p/5284343.html
Copyright © 2020-2023  润新知