Android 3D图片切换

MainActivity

package org.wp.activity;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;

public class MainActivity extends Activity {
	private ViewGroup mContainer;
	private ImageView myFrontIv;
	private ImageView myBackIv;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		mContainer = (ViewGroup) this.findViewById(R.id.mContainer);
		myFrontIv = (ImageView) this.findViewById(R.id.myFrontIv);
		myBackIv = (ImageView) this.findViewById(R.id.myBackIv);
		// 因为要旋转所以我们需要保存视图的缓存信息
		mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);
	
		myFrontIv.setImageBitmap(createReflectedImage(((BitmapDrawable) getResources()
				.getDrawable(R.drawable.picture1)).getBitmap()));
		myBackIv.setImageBitmap(createReflectedImage(((BitmapDrawable) getResources()
				.getDrawable(R.drawable.picture2)).getBitmap()));
	}

	public void showBack(View view) {
		applyRotation(1, 0, 90);
	}

	public void showFront(View view) {
		applyRotation(-1, 0, -90);
	}

	private void applyRotation(int position, float start, float end) {
		final float centerX = mContainer.getWidth() / 2.0f;
		final float centerY = mContainer.getHeight() / 2.0f;

		final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end,
				centerX, centerY, 310.0f, true);
		rotation.setDuration(500);
		rotation.setFillAfter(true);
		// 动画插入器 加速
		rotation.setInterpolator(new AccelerateInterpolator());
		rotation.setAnimationListener(new DisplayNextView(position));

		mContainer.startAnimation(rotation);
	}

	private final class DisplayNextView implements Animation.AnimationListener {
		private final int mPosition;

		private DisplayNextView(int position) {
			mPosition = position;
		}

		@Override
		public void onAnimationStart(Animation arg0) {
		}

		@Override
		public void onAnimationEnd(Animation arg0) {
			mContainer.post(new SwapViews(mPosition));
		}

		@Override
		public void onAnimationRepeat(Animation arg0) {
		}
	}

	private final class SwapViews implements Runnable {
		private final int mPosition;

		public SwapViews(int position) {
			mPosition = position;
		}

		@Override
		public void run() {
			final float centerX = mContainer.getWidth() / 2.0f;
			final float centerY = mContainer.getHeight() / 2.0f;
			Rotate3dAnimation rotation = null;
			if (mPosition > -1) {
				myFrontIv.setVisibility(View.GONE);
				myBackIv.setVisibility(View.VISIBLE);
				myBackIv.requestFocus();

				rotation = new Rotate3dAnimation(-90, 0, centerX, centerY,
						310.0f, false);
			} else {
				myFrontIv.setVisibility(View.VISIBLE);
				myBackIv.setVisibility(View.GONE);
				myFrontIv.requestFocus();

				rotation = new Rotate3dAnimation(90, 0, centerX, centerY,
						310.0f, false);
			}

			rotation.setDuration(500);
			rotation.setFillAfter(true);
			// 动画插入器 减速
			rotation.setInterpolator(new DecelerateInterpolator());

			mContainer.startAnimation(rotation);
		}
	}
	
	private Bitmap createReflectedImage(Bitmap originalBitmap) {
		final int reflectionGap = 4;

		int width = originalBitmap.getWidth();
		int height = originalBitmap.getHeight();

		Matrix matrix = new Matrix();
		matrix.preScale(1, -1);
		Bitmap reflectionBitmap = Bitmap.createBitmap(originalBitmap, 0,
				height / 2, width, height / 2, matrix, false);
		Bitmap withReflectionBitmap = Bitmap.createBitmap(width, (height
				+ height / 2 + reflectionGap), Config.ARGB_8888);

		Canvas canvas = new Canvas(withReflectionBitmap);
		canvas.drawBitmap(originalBitmap, 0, 0, null);

		Paint defaultPaint = new Paint();
		canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);

		canvas.drawBitmap(reflectionBitmap, 0, height + reflectionGap, null);

		Paint paint = new Paint();
		LinearGradient shader = new LinearGradient(0, originalBitmap.getHeight(), 0,
				withReflectionBitmap.getHeight(), 0x70ffffff, 0x00ffffff,
				TileMode.MIRROR);
		paint.setShader(shader);
		paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));

		canvas.drawRect(0, height, width, withReflectionBitmap.getHeight(), paint);

		return withReflectionBitmap;
	}
}

Rotate3dAnimation

package org.wp.activity;

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

public class Rotate3dAnimation extends Animation {
	/** 开始旋转的角度 **/
	private final float mFromDegrees;
	/** 旋转结束的角度 **/
	private final float mToDegrees;
	/** 图片中心X坐标 **/
	private final float mCenterX;
	/** 图片中心Y坐标 **/
	private final float mCenterY;
	/** Z轴上的距离 **/
	private final float mDepthZ;
	/** 缩放效果 **/
	private final boolean mReverse;
	/** 视角 **/
	private Camera mCamera;

	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();
		// x轴 正值向右
		// y轴 正值向上
		// z轴 正值缩小
		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();

		// 旋转矩阵运算会以图像的原点为变换中心点,如果想要以图片中心点为旋转的中心点
		// 就需要首先把整个View的中心移动到原点,矩阵运算完成后再把View移回原来的位置
		matrix.preTranslate(-centerX, -centerY);
		matrix.postTranslate(centerX, centerY);
	}
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" 
	android:layout_height="fill_parent">
	<LinearLayout android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:id="@+id/mContainer">
		<ImageView android:layout_width="fill_parent"
			android:layout_height="fill_parent"
			android:onClick="showBack"
			android:id="@+id/myFrontIv" />
		<ImageView android:layout_width="fill_parent"
			android:layout_height="fill_parent"
			android:onClick="showFront"
			android:visibility="gone"
			android:id="@+id/myBackIv" />	
	</LinearLayout>	
</LinearLayout>

相关推荐