`

API DEMO中3D旋转Layout效果

 
阅读更多
LayoutChange.java:
package cn.com;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.Button;

public class LayoutChange extends Activity {

	ViewGroup layout1, layout2;
	public int order;
	DisplayNextView displayNext;

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

		displayNext = new DisplayNextView(this);

		layout1 = (ViewGroup) findViewById(R.id.layout1);
		Button b1 = (Button) findViewById(R.id.button1);
		b1.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {
				order = 1;
				applyClockInverseRotation(layout1, 0, -90, layout1.getWidth() / 2.0f,
						layout1.getHeight() / 2.0f, true);
			}
		});
	}

	/** 顺时针方向旋转90° */
	public void applyClockwiseRotation(ViewGroup mView, float start, float end, float centerX, float centerY,
			boolean isAddListener) {
		final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, 200.0f,
				isAddListener);
		rotation.setDuration(500);
		rotation.setFillAfter(true);
		rotation.setInterpolator(new AccelerateInterpolator());
		if (isAddListener) {
			rotation.setAnimationListener(displayNext);
		}
		mView.startAnimation(rotation);
	}

	/**
	 * @Description:逆时针方向旋转90°.
	 * 
	 * @param mView
	 *                需要应用动画的View.
	 * @param start
	 *                动画初始角度值.
	 * @param end
	 *                动画结束角度值.
	 * @param centerX
	 *                旋转动画中心点x坐标.
	 * @param centerY
	 *                旋转动画中心点y坐标.
	 * @param mIsAddListener
	 * 
	 * @return void 返回类型
	 */
	public void applyClockInverseRotation(ViewGroup mView, float start, float end, float centerX, float centerY,
			boolean mIsAddListener) {
		final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, 200.0f,
				mIsAddListener);
		rotation.setDuration(500);
		rotation.setFillAfter(true);
		rotation.setInterpolator(new AccelerateInterpolator());
		if (mIsAddListener) {
			rotation.setAnimationListener(displayNext);
		}
		mView.startAnimation(rotation);
	}

	public void jumpToLayout1() {
		setContentView(R.layout.layout1);
		layout1 = (ViewGroup) findViewById(R.id.layout1);
		Button b1 = (Button) findViewById(R.id.button1);
		b1.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {
				order = 1;
				applyClockInverseRotation(layout1, 0, -90, layout1.getWidth() / 2.0f,
						layout1.getHeight() / 2.0f, true);
			}
		});
	}

	public void jumpToLayout2() {
		setContentView(R.layout.layout2);
		layout2 = (ViewGroup) findViewById(R.id.layout2);
		Button b2 = (Button) findViewById(R.id.button2);
		b2.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {
				order = 2;
				applyClockwiseRotation(layout2, 0, 90, layout2.getWidth() / 2.0f,
						layout2.getHeight() / 2.0f, true);
			}
		});
	}
}



Rotate3dAnimation.java:
package cn.com;

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);
	}
}



DisplayNextView.java:
package cn.com;

import android.view.View;
import android.view.animation.Animation;

public class DisplayNextView implements Animation.AnimationListener {
	LayoutChange lc;

	public DisplayNextView(LayoutChange lc) {
		this.lc = lc;
	}

	public void onAnimationStart(Animation animation) {
	}

	public void onAnimationEnd(Animation animation) {
		if (lc.order == 1) {
			lc.layout1.post(new SwapViews());
		}
		if (lc.order == 2) {
			lc.layout2.post(new SwapViews());
		}

	}

	public void onAnimationRepeat(Animation animation) {
	}

	private final class SwapViews implements Runnable {

		public void run() {
			if (lc.order == 1) {
				lc.layout1.setVisibility(View.GONE);
				lc.jumpToLayout2();
				lc.layout2.setVisibility(View.VISIBLE);
				lc.applyClockInverseRotation(lc.layout2, 90, 0, 160, 192, false);
			} else if (lc.order == 2) {
				lc.jumpToLayout1();
				lc.applyClockwiseRotation(lc.layout1, -90, 0, 160, 192, false);
			}

		}
	}
}


3个类文件,自己添加2个含有按钮的Layout既可以实现.
分享到:
评论
1 楼 时间拾贝 2012-02-27  
楼主能否上传一下源代码啊?十分感谢!

相关推荐

Global site tag (gtag.js) - Google Analytics