博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
类凡客诚品的android客户端首页促销图片切换组件的实现
阅读量:4605 次
发布时间:2019-06-09

本文共 13284 字,大约阅读时间需要 44 分钟。

这是我最近做的一个项目使用到的组件,具体效果如下:

这个组件我主要是通过graphics.Camera这个类实现的的景深,能够产生较好的3D翻页效果。

这是在尽量少使用Opengl的情况下的一种轻量级解决方案,这个组件的难点应该是在camera的位置变换以及手势操控上面,下面我把主要代码贴过来:

 

package com.hebin.test;import cm.hebin.test.R;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Camera;import android.graphics.Canvas;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 android.view.animation.Animation;import android.view.animation.LinearInterpolator;import android.view.animation.Transformation;import android.widget.Toast;/** * @ClassName: HotGoodsView.java * @Description:热销品切换展示组件 * @Author: Hebin * @CreateDate: 2012/01/16 * @Version: v1.0.0 *  */public class HotGoodsView extends View {	private Camera mCamera = new Camera();	private Paint mPaint = new Paint();	private Matrix mMatrix = new Matrix();	/*	 * camera調用控制鏡頭位置 mCamera.translate(translate[0], translate[1],	 * translate[2]);	 */	private float[] mMiddleTranslate = new float[3];	private float[] mLeftTranslate = new float[3];	private float[] mRightBelowTranslate = new float[3];	private float[] mRightUpTranslate = new float[3];	// 初始化动画	private MyTransformAnimation mAnimation = new MyTransformAnimation();	private int images[] = { R.drawable.hot1, R.drawable.hot2, R.drawable.hot3,			R.drawable.hot4, R.drawable.hot5 };	private String text[] = { "view1", "view2", "view3", "view4", "view5" };	// 主展示图坐标	private static final float mPositionX = CircleViewActivity.wWidth / 7 - 10;	private static final float mPositionY = CircleViewActivity.wHeight / 15;	// 主視圖Y軸旋轉角度	private static final float mRotateY = -10;	// 主视图标记	private int flag = 0;	// left_right :0初始化,1左滑 2右滑	private int left_right = 0;	// 各視圖座標及旋轉角度參數	private float mLeftRotateY;	private float mMiddleRotateY;	private float mMiddlePositionX;	private float mMiddlePositionY;	private float mLeftPositionX;	private float mLeftPositionY;	// touch事件座標	private float transX;	private float transY;	// 左右滑动及复原动画標記	boolean doToLeftAnimation = false;	boolean doReturnAnimation = false;	boolean doToRightAnimation = false;	// 左右滑动判断标记	private boolean moveToLeft = false;	boolean click = false;	private Context context;	public HotGoodsView(Context context, AttributeSet attrs) {		super(context, attrs);		// 抗锯齿		mPaint.setAntiAlias(true);		this.context = context;		init();	}	// 初始化、重置参数	private void init() {		mMiddlePositionX = mPositionX;		mMiddlePositionY = mPositionY;		mMiddleRotateY = mRotateY;		mLeftPositionX = -80 - mPositionX * 7 / 2;		mLeftPositionY = mPositionY;		mLeftRotateY = 0;		transX = 0;		transY = 0;		mMiddleTranslate[0] = 0;		mMiddleTranslate[1] = 0;		mMiddleTranslate[2] = 0;		mRightUpTranslate[0] = 30;		mRightUpTranslate[1] = -10;		mRightUpTranslate[2] = 50;		mRightBelowTranslate[0] = 60;		mRightBelowTranslate[1] = -20;		mRightBelowTranslate[2] = 100;		doToLeftAnimation = false;		doToRightAnimation = false;		doReturnAnimation = false;		left_right = 0;		System.gc();	}	@Override	protected void onDraw(Canvas canvas) {		drawRight(canvas);		drawMiddle(canvas);		drawLeft(canvas);		super.onDraw(canvas);	}	private void drawMiddle(Canvas canvas) {		doDraw(mMiddleRotateY, mMiddleTranslate, canvas, mMiddlePositionX,				mMiddlePositionY, images[flag]);	}	private void drawLeft(Canvas canvas) {		Log.e("sss", mLeftRotateY + " " + mLeftTranslate + " " + mLeftPositionX				+ " " + mLeftPositionY + " " + (flag - 1));		if (flag != 0)			doDraw(mLeftRotateY, mLeftTranslate, canvas, mLeftPositionX,					mLeftPositionY, images[flag - 1]);	}	private void drawRight(Canvas canvas) {		if ((flag != images.length - 2) && (flag != images.length - 1))			doDraw(mRotateY, mRightBelowTranslate, canvas, mPositionX,					mPositionY, images[flag + 2]);		if (flag != images.length - 1)			doDraw(mRotateY, mRightUpTranslate, canvas, mPositionX, mPositionY,					images[flag + 1]);	}	public int getFlag() {		return flag;	}	public void setFlag(int flag) {		this.flag = flag;	}	public String[] getText() {		return text;	}	public void setText(String[] text) {		this.text = text;	}	/**	 * 	 * @MethodName:onTouchEvent	 * @Author: Hebin	 * @Description:触摸判断	 * @CreateDate: 2012/01/16	 */	@Override	public boolean onTouchEvent(MotionEvent event) {		switch (event.getAction()) {		case MotionEvent.ACTION_DOWN:			click = true;			// 捕捉touch座標			transX = event.getX();			transY = event.getY();			// Log.e("xxx", transX + " " + transY);			break;		case MotionEvent.ACTION_MOVE:			moveToLeft = ((event.getX() - transX) < 0);			click = false;			Log.e("xxxx", left_right + "");			// 判斷左右滑動			if (moveToLeft) {				// 判斷左滑過程中是否曾經右滑(区分手指不離開屏幕左右滑動和其他情況)				if (left_right != 2) { // left_right為0或1;					if (mMiddlePositionX > -10 - mPositionX * 7 / 2) {// 判斷主視圖是否滑動到左側邊緣						// 主视图随手势移动						mMiddlePositionX += (event.getX() - transX);						mLeftPositionX += (event.getX() - transX);						// Log.e("xx", event.getX() + " " + transX + " "						// + (event.getX() - transX));						// 主視圖旋轉						mMiddleRotateY -= ((event.getX() - transX) / 230) * 20;						// Log.e("xx", mMiddleRotateY + "");						// 右側層疊視圖按軌道上升						mRightUpTranslate[0] -= ((transX - event.getX()) / 8);						mRightUpTranslate[1] += ((transX - event.getX())) / 25;						mRightUpTranslate[2] -= ((transX - event.getX())) * 5 / 23;						// Log.e("xxx", mRightUpTranslate[0] + "");						// Log.e("xx", "ACTION_MOVE:" + mMiddlePositionX);						mRightBelowTranslate[0] -= ((transX - event.getX())) / 8;						mRightBelowTranslate[1] += ((transX - event.getX())) / 25;						mRightBelowTranslate[2] -= ((transX - event.getX())) * 5 / 23;					}					left_right = 1;				} else {					// left_right=2;左滑过程中曾经右滑					if (mLeftPositionX > -80 - mPositionX * 7 / 2) {						mLeftRotateY -= ((event.getX() - transX) / 230) * 10;						mLeftPositionX += (event.getX() - transX);						// Log.e("xx", mMiddleRotateY + "");						mMiddleTranslate[0] -= ((transX - event.getX()) / 8);						mMiddleTranslate[1] += ((transX - event.getX())) / 25;						mMiddleTranslate[2] -= ((transX - event.getX())) * 5 / 23;						// Log.e("xxx", mRightUpTranslate[0] + "");						// Log.e("xx", "ACTION_MOVE:" + mMiddlePositionX);						mRightUpTranslate[0] -= ((transX - event.getX())) / 8;						mRightUpTranslate[1] += ((transX - event.getX())) / 25;						mRightUpTranslate[2] -= ((transX - event.getX())) * 5 / 23;						mRightBelowTranslate[0] -= ((transX - event.getX())) * 1 / 5;						mRightBelowTranslate[1] += ((transX - event.getX())) / 23;						mRightBelowTranslate[2] -= ((transX - event.getX())) * 10 / 23;					}				}			} else if ((event.getX() - transX) != 0) {// 右滑				Log.e("xxxxxx", left_right + "else");				if (left_right != 1) {// left_right=0或2;					if (mLeftPositionX < mPositionX) {// 判斷右滑邊界						mLeftRotateY -= ((event.getX() - transX) / 230) * 10;						mLeftPositionX += (event.getX() - transX);						// Log.e("xx", mMiddleRotateY + "");						mMiddleTranslate[0] -= ((transX - event.getX()) / 8);						mMiddleTranslate[1] += ((transX - event.getX())) / 25;						mMiddleTranslate[2] -= ((transX - event.getX())) * 5 / 23;						// Log.e("xxx", mRightUpTranslate[0] + "");						// Log.e("xx", "ACTION_MOVE:" + mMiddlePositionX);						mRightUpTranslate[0] -= ((transX - event.getX())) / 8;						mRightUpTranslate[1] += ((transX - event.getX())) / 25;						mRightUpTranslate[2] -= ((transX - event.getX())) * 5 / 23;						mRightBelowTranslate[0] -= ((transX - event.getX())) * 1 / 5;						mRightBelowTranslate[1] += ((transX - event.getX())) / 23;						mRightBelowTranslate[2] -= ((transX - event.getX())) * 10 / 23;					}					left_right = 2;				} else {					if (mMiddlePositionX < mPositionX) {						mMiddlePositionX += (event.getX() - transX);						mLeftPositionX += (event.getX() - transX);						// Log.e("xx", event.getX() + " " + transX + " "						// + (event.getX() - transX));						mMiddleRotateY -= ((event.getX() - transX) / 230) * 20;						// Log.e("xx", mMiddleRotateY + "");						mRightUpTranslate[0] -= ((transX - event.getX()) / 8);						mRightUpTranslate[1] += ((transX - event.getX())) / 25;						mRightUpTranslate[2] -= ((transX - event.getX())) * 5 / 23;						// Log.e("xxx", mRightUpTranslate[0] + "");						// Log.e("xx", "ACTION_MOVE:" + mMiddlePositionX);						mRightBelowTranslate[0] -= ((transX - event.getX())) / 10;						mRightBelowTranslate[1] += ((transX - event.getX())) / 30;						mRightBelowTranslate[2] -= ((transX - event.getX())) * 5 / 23;					}				}			}			invalidate();			// 滑动过程动态赋值			transX = event.getX();			transY = event.getY();			break;		case MotionEvent.ACTION_UP:			if (click) {				Toast.makeText(context, text[flag], Toast.LENGTH_LONG).show();			}			// touch结束开始动画			// Log.e("xxx", mMiddleRotateY + "");			if (moveToLeft) {// 左滑動畫				if ((mMiddlePositionX - mPositionX) < -CircleViewActivity.wWidth / 4) {					Log.e("xxxx", "qqqqqqqqqq");					doToLeftAnimation = true;					startAnimation(mAnimation);				} else {					doReturnAnimation = true;					startAnimation(mAnimation);				}			} else {// 右滑動畫				if ((mLeftPositionX - (-80 - CircleViewActivity.wWidth / 2)) > CircleViewActivity.wWidth / 4						&& flag > 0) {					doToRightAnimation = true;					startAnimation(mAnimation);				} else {					doReturnAnimation = true;					startAnimation(mAnimation);				}			}			break;		default:			break;		}		return true;	}	/**	 * 	 * @MethodName:doDraw	 * @Author: Hebin	 * @Description:实际绘图类	 * @CreateDate: 2012/01/16	 */	private void doDraw(float rotateY, float[] translate, Canvas canvas,			float x, float y, int image) {		canvas.save();		mCamera.save();		mCamera.rotateY(rotateY);		mCamera.translate(translate[0], translate[1], translate[2]);		mCamera.getMatrix(mMatrix);		mCamera.applyToCanvas(canvas);		Bitmap bitmap = BitmapFactory.decodeResource(getResources(), image);		canvas.drawBitmap(bitmap, x, y, mPaint);		bitmap.recycle();		mCamera.restore();		canvas.restore();	}	/**	 * @ClassName: MyTransformAnimation.java	 * @Description:切換動畫	 * @Author: Hebin	 * @CreateDate: 2012/01/16	 * @Version: v1.0.0	 * @parameters: doToLeftAnimation = false; doReturnAnimation = false;	 *              doToRightAnimation = false;	 */	class MyTransformAnimation extends Animation {		@Override		protected void applyTransformation(float interpolatedTime,				Transformation t) {			if (doToLeftAnimation) {// 左滑动画				mMiddlePositionX -= (mMiddlePositionX + 80 + mPositionX * 7 / 2)						* interpolatedTime;				mMiddleRotateY += (0 - mMiddleRotateY) * interpolatedTime;				mRightUpTranslate[0] += (0 - mRightUpTranslate[0])						* interpolatedTime;				mRightUpTranslate[1] += (0 - mRightUpTranslate[1])						* interpolatedTime;				mRightUpTranslate[2] += (0 - mRightUpTranslate[2])						* interpolatedTime;				mRightBelowTranslate[0] += (30 - mRightBelowTranslate[0])						* interpolatedTime;				mRightBelowTranslate[1] += (-10 - mRightBelowTranslate[1])						* interpolatedTime;				mRightBelowTranslate[2] += (50 - mRightBelowTranslate[2])						* interpolatedTime;				// Log.e("", mRightUpTranslate[0] + "");			}			if (doReturnAnimation) {// 復原動畫				mMiddlePositionX -= (mMiddlePositionX - mPositionX)						* interpolatedTime;				mMiddleRotateY -= (mMiddleRotateY + 15) * interpolatedTime;				mLeftPositionX -= (mLeftPositionX + 80 + mPositionX * 7 / 2)						* interpolatedTime;				mLeftRotateY += (0 - mLeftRotateY) * interpolatedTime;				// Log.e("xx", "doReturnAnimation:" + mMiddlePositionX);			}			if (doToRightAnimation) {// 右滑动画				// Log.e("ee", "doToRightAnimation");				mLeftPositionX -= (mLeftPositionX - mPositionX)						* interpolatedTime;				mLeftRotateY += (-10 - mLeftRotateY) * interpolatedTime;				// Log.e("xxx", mLeftPositionX + "");				// Log.e("xx", mPositionX + "");				mMiddleTranslate[0] += (30 - mMiddleTranslate[0])						* interpolatedTime;				mMiddleTranslate[1] += (-10 - mMiddleTranslate[1])						* interpolatedTime;				mMiddleTranslate[2] += (50 - mMiddleTranslate[2])						* interpolatedTime;				mRightUpTranslate[0] += (60 - mRightUpTranslate[0])						* interpolatedTime;				mRightUpTranslate[1] += (-20 - mRightUpTranslate[1])						* interpolatedTime;				mRightUpTranslate[2] += (100 - mRightUpTranslate[2])						* interpolatedTime;				mRightBelowTranslate[0] += (120 - mRightBelowTranslate[0])						* interpolatedTime;				mRightBelowTranslate[1] += (-40 - mRightBelowTranslate[1])						* interpolatedTime;				mRightBelowTranslate[2] += (200 - mRightBelowTranslate[2])						* interpolatedTime;			}			super.applyTransformation(interpolatedTime, t);		}		// 動畫初始化		@Override		public void initialize(int width, int height, int parentWidth,				int parentHeight) {			// Log.e("xx", "initialize");			super.initialize(width, height, parentWidth, parentHeight);			setDuration(250);			setFillAfter(true);			setInterpolator(new LinearInterpolator());		}	}	@Override	protected void onAnimationEnd() {		// 动画结束更新flag标记		if (doToLeftAnimation) {			if (flag < images.length - 1)				flag++;		}		if (doToRightAnimation) {			if (flag > 0)				flag--;		}		// 所有动态参数在动画结束后重置		init();		Log.e("xxxx", left_right + "onAnimationEnd");		super.onAnimationEnd();	}	@Override	protected void onAnimationStart() {		super.onAnimationStart();	}}

我注释写的很详细,就不一一再解释什么。这部分代码写的比较原始,没做太多优化。

转载于:https://www.cnblogs.com/hisneric/archive/2012/01/16/2324184.html

你可能感兴趣的文章
Minimum Path Sum
查看>>
Remove Duplicates from Sorted Array II
查看>>
常量指针和指针常量巧妙记忆方法[转]
查看>>
python-haproxy作业讲解视频总结
查看>>
批处理文件脚本总结
查看>>
快速排序C++代码
查看>>
mui搜索框 搜索点击事件
查看>>
bzoj 5289: [Hnoi2018]排列
查看>>
joomla处境堪忧
查看>>
Jquery-AJAX
查看>>
A == B ?
查看>>
洛谷P3763 [Tjoi2017]DNA 【后缀数组】
查看>>
UVa 442 Matrix Chain Multiplication(矩阵链,模拟栈)
查看>>
多种方法求解八数码问题
查看>>
spring mvc ModelAndView向前台传值
查看>>
(黑客游戏)HackTheGame1.21 过关攻略
查看>>
Transparency Tutorial with C# - Part 2
查看>>
android 文件上传
查看>>
ASCII 码表对照
查看>>
javascript的DOM操作获取元素
查看>>