两个activity的3D翻转动画.md

一.业务需求

这里在公司项目设计时,用到了一个小的需求,就是点击一个按钮然后整个activity的页面进行3d翻转;

二.设计思路

由于是2个activity的之间的翻转动画,就意味着前90度是A页面进行翻转翻转结束后B页面从90到0度完成整个翻转过程;再从B翻转到A也是同样,B先翻转90度然后A再从90度翻转到0度,这样就完成了一个衔接;
那么这里就需要一个3D的翻转类,

三.代码实现

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

/**
 * An animation that rotates the view on the Y axis between two specified angles.
 * This animation also adds a translation on the Z axis (depth) to improve the effect.
 */
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;

    /**
     * Creates a new 3D rotation on the Y axis. The rotation is defined by its
     * start angle and its end angle. Both angles are in degrees. The rotation
     * is performed around a center point on the 2D space, definied by a pair
     * of X and Y coordinates, called centerX and centerY. When the animation
     * starts, a translation on the Z axis (depth) is performed. The length
     * of the translation can be specified, as well as whether the translation
     * should be reversed in time.
     *
     * @param fromDegrees the start angle of the 3D rotation
     * @param toDegrees the end angle of the 3D rotation
     * @param centerX the X center of the 3D rotation
     * @param centerY the Y center of the 3D rotation
     * @param reverse true if the translation should be reversed, false otherwise
     */
    public Rotate3dAnimation(float fromDegrees, float toDegrees,
                             float centerX, float centerY, float depthZ, boolean reverse) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;
        mCenterX = centerX;
        mCenterY = centerY;
        mDepthZ = depthZ;
        mReverse = reverse;
    }

    @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));
        }
        camera.rotateY(degrees);
        camera.getMatrix(matrix);
        camera.restore();

        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);
    }
}


import android.app.Activity;
import android.util.Log;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;

public class RotationHelper {

    DisplayNextView displayNext;

    public RotationHelper(Activity con,int order){
        displayNext = new DisplayNextView(con, order);
    }

    // 逆时针旋转90
    public void applyFirstRotation(ViewGroup layout,float start, float end) {
        // Find the center of the container
        final float centerX = layout.getWidth() / 2.0f;
        final float centerY = layout.getHeight() / 2.0f;
        Log.i("centerX =" + centerX, "centerX");
        Log.i("centerY =" + centerY, "centerY");

        // Create a new 3D rotation with the supplied parameter
        // The animation listener is used to trigger the next animation
        final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end,
                centerX, centerY, 310.0f, true);
        rotation.setDuration(700);
        rotation.setFillAfter(true);
        rotation.setInterpolator(new AccelerateInterpolator());
        rotation.setAnimationListener(displayNext);
        layout.startAnimation(rotation);
    }

    public void applyLastRotation(ViewGroup layout,float start, float end) {
        // Find the center of the container
        final float centerX = layout.getWidth() / 2.0f;
        final float centerY = layout.getHeight() / 2.0f;
        Log.i("centerX =" + centerX, "centerX");
        Log.i("centerY =" + centerY, "centerY");

        // Create a new 3D rotation with the supplied parameter
        // The animation listener is used to trigger the next animation
        final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end,
                160, 192, 310.0f, false);
        rotation.setDuration(700);
        rotation.setFillAfter(true);
        rotation.setInterpolator(new AccelerateInterpolator());
        layout.startAnimation(rotation);
    }
}


import android.app.Activity;
import android.view.animation.Animation;

public class DisplayNextView implements Animation.AnimationListener {

    Object obj;

    // 动画监听器的构造函数
    Activity ac;
    int order;

    public DisplayNextView(Activity ac, int order) {
        this.ac = ac;
        this.order = order;
    }

    public void onAnimationStart(Animation animation) {
    }

    public void onAnimationEnd(Animation animation) {
        doSomethingOnEnd(order);
    }

    public void onAnimationRepeat(Animation animation) {
    }

    private final class SwapViews implements Runnable {
        public void run() {
            switch (order) {
                case Constants.KEY_FIRST_INVERSE:
                    ((TranslateLayout) ac).jumpToSecond();
                    break;
                case Constants.KEY_SECOND_CLOCKWISE:
                    ((Second) ac).jumpToFirst();
                    break;
            }
        }
    }

    //动画完成的监听
    public void doSomethingOnEnd(int _order) {
        switch (_order) {
            case Constants.KEY_FIRST_INVERSE:
                ((TranslateLayout) ac).layout1.post(new SwapViews());
                break;

            case Constants.KEY_SECOND_CLOCKWISE:
                ((Second) ac).layout2.post(new SwapViews());
                break;
        }
    }
}
public class Constants {//相关常量

    public final static int KEY_FIRST_INVERSE = 1;

    public final static int KEY_FIRST_CLOCKWISE = 2;

    public final static int KEY_SECOND_INVERSE = 3;

    public final static int KEY_SECOND_CLOCKWISE = 4;
}

//第一个页面
public class TranslateLayout extends Activity implements OnClickListener {

    RelativeLayout layout1;

    String tag="";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first);
        ImageView first_btn = (ImageView) findViewById(R.id.first_btn);
        first_btn.setOnClickListener(this);

        layout1 = (RelativeLayout) findViewById(R.id.layout1);
        showView();

    }

    public void showView() {
        /* 取得Intent中的Bundle对象 */
        Bundle bundle = this.getIntent().getExtras();

        if (bundle != null) {
            /* 取得Bundle对象中的数据 */
            tag = bundle.getString("second","");
            Log.d("first_tag",tag);
            if (tag.equals("Second")) {
                rotateHelper = new RotationHelper(this,
                        Constants.KEY_FIRST_CLOCKWISE);
                rotateHelper.applyLastRotation(layout1, -90, 0);
            }
        }
    }

    RotationHelper rotateHelper;

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        rotateHelper = new RotationHelper(this, Constants.KEY_FIRST_INVERSE);
        rotateHelper.applyFirstRotation(layout1, 0, -90);
    }

    @Override
    protected void onPause() {
        overridePendingTransition(0, 0);
        super.onPause();
    }

    public void jumpToSecond() {
        Intent in = new Intent();
        in.setClass(this, Second.class);
        // new一个Bundle对象,并将要传递的数据传入
        Bundle bundle = new Bundle();
        bundle.putString("front", "First");
        /* 将Bundle对象assign给Intent */
        in.putExtras(bundle);
        // 如果已经打开过的实例,将不会重新打开新的Activity
        startActivity(in);
        //关闭掉动画
        overridePendingTransition(0, 0);
    }

}
/**
 * Created by cxf on 2017/9/13.
 *
 * @title
 * @describe
 * @email chenxianfu_it@163.com
 */


//第二个页面
public class Second extends Activity implements OnClickListener {

    String tag = "";

    RotationHelper rotateHelper;

    RelativeLayout layout2;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);

        layout2 = (RelativeLayout) findViewById(R.id.layout2);
        showView();
        setListener();
    }

    public void setListener() {
        ImageView second_btn = (ImageView) findViewById(R.id.second_btn);
        second_btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        rotateHelper = new RotationHelper(this,
                Constants.KEY_SECOND_CLOCKWISE);
        rotateHelper.applyFirstRotation(layout2, 0, 90);
    }

    public void showView() {
        /* 取得Intent中的Bundle对象 */
        Bundle bundle = this.getIntent().getExtras();

        if (bundle != null) {
            /* 取得Bundle对象中的数据 */
            tag = bundle.getString("front");
        }

        System.out.println("bundle =" + tag);

        if (tag.equals("First")) {
            rotateHelper = new RotationHelper(this, Constants.KEY_SECOND_INVERSE);
            rotateHelper.applyLastRotation(layout2, 90, 0);
        }
    }

    @Override
    protected void onDestroy() {
        overridePendingTransition(0, 0);
        super.onDestroy();
    }

    public void jumpToFirst() {
        Intent in = new Intent();
        in.setClass(this, TranslateLayout.class);
        Bundle bundle = new Bundle();
        bundle.putString("second", "Second");
        in.putExtras(bundle);
        startActivity(in);
        overridePendingTransition(0, 0);
        finish();
    }

}
posted @ 2017-09-18 19:10  一粒尘_PM  阅读(1704)  评论(0编辑  收藏  举报

Android应用开发&研究 - 创建于 2017年8月17日

这是一位Android开发工程师的个人站,内容主要是网站开发方面的技术文章,大部分来自学习或工作,部分来源于网络,希望对大家有所帮助。

致力于Android应用开发&研究工作,专注移动开发,关注互联网前沿技术与趋势。


Font Awesome | Respond.js | Bootstrap中文网