Android开发Android开发Android技术知识

Andorid 广告页3D旋转进入主页(仿ios Swift动画

2018-09-17  本文已影响10人  Ready_I
20170731131804631.gif

1,Android 原本一些overridePendingTransition 用来跳转activity切换动画,并不支持那么完美的3d旋转动画,有些手机并不能支持
2,利用Activity继承ActivityGroup(不支持使用该方法),包裹两个Activity,通过获取该view,addview到该Group的布局中,经过测试,太卡

但是需求必须得做,就找到一个鸡贼的办法
1,广告页和主界面 写在同一个Activity中
2,使用广告页覆盖主页面,在Activity动画旋转90度后,隐藏并把Activty反着旋转90度,已达到以上图片效果
3,把主界面中耗时操作,消耗性能操作,绘制操作等,尽量放在动画结束之后。防止卡顿

Observable.just(1)
                .delay(2500, TimeUnit.MILLISECONDS)
                .observeOn(Schedulers.newThread())
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        if (go) {
                            mboss.post(new Runnable() {//根部局绘制完成
                                @Override
                                public void run() {
                                    Rotate3dAnimation flipAinm = new Rotate3dAnimation(MainActivity.this, 360, 270, centerX, centerY, 0f, true);
                                    flipAinm.setFillAfter(true);
                                    flipAinm.setAnimationListener(new Animation.AnimationListener() {
                                        @Override
                                        public void onAnimationStart(Animation animation) {
                                        }

                                        @Override
                                        public void onAnimationEnd(Animation animation) {
                                            mfragm_img.setVisibility(View.GONE);
                                            playFlip2Anim();
                                        }

                                        @Override
                                        public void onAnimationRepeat(Animation animation) {

                                        }
                                    });
                                    flipAinm.setInterpolator(new AccelerateInterpolator());
                                    flipAinm.setDuration(800);
                                    mboss.clearAnimation();
                                    mboss.startAnimation(flipAinm);     
                                }
                            });
                        }
                    }
                });

第一部分90度旋转完成后,执行第二部分

private void playFlip2Anim(){
        Rotate3dAnimation flipAinm = new Rotate3dAnimation(MainActivity.this, 90, 0, centerX, centerY, 0f, true);
        flipAinm.setFillAfter(true);
        flipAinm.setInterpolator(new AccelerateInterpolator());
        flipAinm.setDuration(800);
        flipAinm.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                
            }

            @Override
            public void onAnimationEnd(Animation animation) {
             //在此执行主界面逻辑
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        mboss.clearAnimation();
        mboss.startAnimation(flipAinm);
    }
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();

        // 修正失真,主要修改 MPERSP_0 和 MPERSP_1
        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);
        matrix.postTranslate(centerX, centerY);
    }
}
上一篇下一篇

猜你喜欢

热点阅读