使用Camera实现3d翻转效果

废话不多说上代码
package com.rote.ui;

import java.io.IOException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.rote.util.BitmapUtil;

public class FlingView extends View {
	private Camera mCamera;
	private Bitmap mBitmap;
	private Matrix mMatrix;
	private Paint mPaint;

	private int mScreenWidth, mScreenHeight;
	private int mWidth, mHeight;

	private Context mContext;
	private int mDeltaY;
	private boolean mIsReseting;
	private Timer mFlingTimer;

	public FlingView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		mCamera = new Camera();
		mMatrix = new Matrix();
		mPaint = new Paint();
		mFlingTimer = new Timer();
		initData();
	}

	private void initData() {
		setWillNotDraw(false);
		mScreenHeight = 1024;
		mScreenWidth = 800;
		mPaint.setAntiAlias(true);
	}

	@Override
	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		canvas.drawColor(Color.BLACK);
		if (mBitmap != null) {
			// 先根据图片的高宽计算出要在屏幕中间画出图片需要的设置的x,y轴偏移量
			canvas.translate((mScreenWidth - mWidth) >> 1,
					(mScreenHeight - mHeight) >> 1);
			canvas.drawBitmap(mBitmap, mMatrix, mPaint);
		}
	}

	/**
	 * 功能简述:旋转照相机角度来改变观看视图
	 * 
	 * @param degreeY
	 *            在原来的基础上,翻转的角度
	 */
	public void rotate(int degreeY) {
		mIsReseting = false;
		mDeltaY += degreeY;
		mCamera.save();
		mCamera.rotateX(mDeltaY);
		mCamera.getMatrix(mMatrix);
		mCamera.restore();
		mMatrix.preTranslate(-mWidth >> 1, -mHeight >> 1);
		mMatrix.postTranslate(mWidth >> 1, mHeight >> 1);
		mCamera.save();
		postInvalidate();
	}

	/**
	 * 功能简述: 图片翻转后可调用此方法回复原来的图片
	 * 
	 */
	public void resetRotate() {
		mIsReseting = true;
		mDeltaY %= 360;
		invalidate();
	}

	public void setBitmap(String path) {

		try {
			mBitmap = BitmapUtil.getBitMap(
					getResources().getAssets().open("image/" + path),
					mScreenWidth, mScreenHeight);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int height = mBitmap.getHeight();
		int width = mBitmap.getWidth();
		if ((double) height / width > (double) mScreenHeight / mScreenWidth) {
			// 当原图高宽比大于屏幕高宽比时,以屏幕高为图片的高,同比例计算图片的新宽度
			width = width * mScreenHeight / height;
			mBitmap = Bitmap.createScaledBitmap(mBitmap, width, mScreenHeight,
					true);
		} else {

			// 当原图高宽比小于屏幕高宽比时,以屏幕宽为图片的宽,同比例计算图片的新高度
			height = height * mScreenWidth / width;
			mBitmap = Bitmap.createScaledBitmap(mBitmap, mScreenWidth, height,
					true);
		}
		mWidth = mBitmap.getWidth();
		mHeight = mBitmap.getHeight();
		invalidate();
	}

	private int startX, startY;
	private int endX, endY;
	private int middleX, middleY;
	private boolean mIsUpDownFling;

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int i = event.getAction();
		switch (i) {
		case MotionEvent.ACTION_DOWN:
			resetRotate();
			startX = (int) event.getX();
			startY = (int) event.getY();
			mIsUpDownFling = false;
			// Log.e("cancel", "ACTION_DOWN");
			break;
		case MotionEvent.ACTION_MOVE:

			// rotate(middleY - startX);

			endY = (int) event.getY();

			middleY = (int) event.getY();
			// Log.e("cancel", "ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			endX = (int) event.getX();
			endY = (int) event.getY();
			mIsUpDownFling = true;
			mFlingTimer.schedule(new RoteThread(endY - startY), new Date());
			// Log.e("cancel", "ACTION_UP");
			break;
		case MotionEvent.ACTION_CANCEL:

			break;

		default:
			break;
		}
		return true;
	}

	public class RoteThread extends TimerTask {
		private float mVelocity;

		public RoteThread(float velocity) {
			mVelocity = velocity;
		}

		@Override
		public void run() {
			mDeltaY = 360;
			// Math.abs(mVelocity) > 20 &&
			while (mIsUpDownFling && mDeltaY != 0) {
				// mDeltaY -= mVelocity / 10;
				// mVelocity *= 0.9;
				mDeltaY -= 10;
				rotate(0);
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			mIsUpDownFling = false;
		}

	}

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值