AndroidAndroid笔记Android Studio

Android 3D旋转动画库

2017-09-01  本文已影响399人  代码君_Coder

今天兴趣来潮,撸了一个动画特效,我把他应用在登录的界面,当然也可以用在其他地方,先来预览一下我的特效吧

预览.gif

使用方法

  1. 在build.gradle里面配置如下
dependencies {
  compile 'com.jzp:rotate3D:1.0.0'
}
  1. 生成一个Rotate3D对象
   Rotate3D  anim = new Rotate3D.Builder(this)
            .bindParentView(parent_ll)
            .bindPositiveView(account_login_ll)
            .bindNegativeView(account_phone_ll)
            .create();

这里面必须要设置的参数是bindParentView,bindPositiveView,bindNegativeView,这些分别是父类View,正面View,以及旋转后的反面View,有提供可选参数

  1. 启动动画
   anim.transform();

实现原理

由于android提供的动画 alpha(淡入淡出),translate(位移),scale(缩放大小),rotate(旋转),这些都是平面上的动画,那想要做3D立体的动画,我们就需要从写animation,3D立体动画用到android的Camera库,Camera提供了三种旋转方法:

实现的核心代码

public class Rotate3dAnimation extends Animation {
    private final float mFromDegrees;
    private final float mToDegrees;
    private final float mCenterX;
    private final float mCenterY;
    private final float mDepthZ;
    private final boolean mReverse;
    private Camera mCamera;
    float scale = 1;    // 像素密度

    /**
     * 创建一个绕 y 轴旋转的3D动画效果,旋转过程中具有深度调节,可以指定旋转中心。
     *
     * @param context     上下文,用于获取像素密度
     * @param fromDegrees 起始时角度
     * @param toDegrees   结束时角度
     * @param centerX     旋转中心x坐标
     * @param centerY     旋转中心y坐标
     * @param depthZ      最远到达的z轴坐标
     * @param reverse     true 表示由从0到depthZ,false相反
     */

    public Rotate3dAnimation(Context context, float fromDegrees, float toDegrees,
                             float centerX, float centerY, float depthZ, boolean reverse) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;
        mCenterX = centerX;
        mCenterY = centerY;
        mDepthZ = depthZ;
        mReverse = reverse;
        // 获取手机像素密度 (即dp与px的比例)
        scale = context.getResources().getDisplayMetrics().density;
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mCamera = new Camera();
    }

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

        final float centerX = mCenterX;
        final float centerY = mCenterY;
        final Camera camera = mCamera;
        final Matrix matrix = t.getMatrix();

        camera.save();
        // 调节深度
        if (mReverse) {
            camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
        } else {
            camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
        }
        // 绕y轴旋转
        camera.rotateY(degrees);
        camera.getMatrix(matrix);
        camera.restore();

        // 修正失真
        float[] mValues = new float[9];
        matrix.getValues(mValues);                //获取数值
        mValues[6] = mValues[6] / scale;            //数值修正
        mValues[7] = mValues[7] / scale;            //数值修正
        matrix.setValues(mValues);                //重新赋值

        // 调节中心点,旋转中心默认是坐标原点,对于图片来说就是左上角位置。
        matrix.preTranslate(-centerX, -centerY); // 使用pre将旋转中心移动到和Camera位置相同
        matrix.postTranslate(centerX, centerY);  // 使用post将图片(View)移动到原来的位置
    }
}

总结

代码中的作用我都有写注释,所以在这里就不多解释了,有的时候,我们看一些特效觉得做起来一定很麻烦,其实只要你掌握其实现原理,并不是很难,所以给大家一句忠告,多读源码,对技术的提升很有帮助。

参考文献:http://www.jianshu.com/p/153d9f31288d 我是根据这篇博客进行封装的,谢谢亦枫大神的分享

Github源码下载:3D旋转动画库

上一篇下一篇

猜你喜欢

热点阅读