码迷,mamicode.com
首页 > 其他好文 > 详细

手势密码(一)

时间:2015-06-11 17:04:35      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:touchevent motionev   九宫格 密码锁   

技术分享

ImageLockActivity

package com.example.imagelock;

import com.example.view.NinePointLineView;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;

public class ImageLockActivity extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		View v = new NinePointLineView(this);
		setContentView(v);
	}
}

NinePointLineView

package com.example.view;

import com.example.imagelock.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

public class NinePointLineView extends View {

	/**
	 * 定义3个Paint,还有一个坐标圆点图片
	 */
	Paint linePaint = new Paint();
	Paint whiteLinePaint = new Paint();
	Paint textPaint = new Paint();
	Bitmap defaultBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.lock);
	
	PointInfo[] points = new PointInfo[9];
	int width, height;
	//坐标点的半径长度
	int defaultBitmapRadius = defaultBitmap.getWidth() / 2;

	//绘制密码时候出现的原点的直径,半径
	Bitmap selectedBitmap = BitmapFactory.decodeResource(getResources(),
			R.drawable.indicator_lock_area);
	int selectedBitmapDiameter = selectedBitmap.getWidth();
	int selectedBitmapRadius = selectedBitmapDiameter / 2;
	
	StringBuffer lockString = new StringBuffer();

	Context context;
	/** 构造器*********************************************/
	public NinePointLineView(Context context) {
		super(context);
		this.context = context;
		this.setBackgroundColor(Color.WHITE);
		initPaint();
	}

	public NinePointLineView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
		this.setBackgroundColor(Color.WHITE);
		initPaint();
	}
	private void initPaint() {
		//线--包裹9个原点
		linePaint.setColor(Color.RED);
		linePaint.setStrokeWidth(defaultBitmap.getWidth());
		linePaint.setAntiAlias(true);
		linePaint.setStrokeCap(Cap.ROUND);
		//线内--比原点直径少5
		whiteLinePaint.setColor(Color.GREEN);
		whiteLinePaint.setStrokeWidth(defaultBitmap.getWidth() - 5);
		whiteLinePaint.setAntiAlias(true);
		whiteLinePaint.setStrokeCap(Cap.ROUND);
		//字体设置
		textPaint.setTextSize(30);
		textPaint.setAntiAlias(true);
		textPaint.setTypeface(Typeface.MONOSPACE);
	}

	/**********************************************************
	 * 测量
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		width = getWidth();
		height = getHeight();
		if (width != 0 && height != 0) {
			initPoints(points);
		}
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	/**
	 * 初始化原点
	 */
	private void initPoints(PointInfo[] points) {

		int len = points.length;

		//2个原点的间距
		int seletedSpacing = (width - selectedBitmapDiameter * 3) / 4;

		//第1个原点的坐标
		int seletedX = seletedSpacing;
		int seletedY = height - width + seletedSpacing;

		//第1个原点内部的小圆的坐标
		int defaultX = seletedX + selectedBitmapRadius - defaultBitmapRadius;
		int defaultY = seletedY + selectedBitmapRadius - defaultBitmapRadius;

		for (int i = 0; i < len; i++) {
			//第4、7个原点
			if (i == 3 || i == 6) {
				seletedX = seletedSpacing;
				//第一个原点y坐标+直径+2点间距离
				seletedY += selectedBitmapDiameter + seletedSpacing;

				defaultX = seletedX + selectedBitmapRadius
						- defaultBitmapRadius;
				//第一个原点y坐标+直径+2点间距离
				defaultY += selectedBitmapDiameter + seletedSpacing;

			}
			points[i] = new PointInfo(i, defaultX, defaultY, seletedX, seletedY);

			//原点坐标xy为直径+2点间距离
			seletedX += selectedBitmapDiameter + seletedSpacing;
			defaultX += selectedBitmapDiameter + seletedSpacing;

		}
	}
	/*****************************************************************/
	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);
	}

	private int startX = 0, startY = 0;
	PointInfo startPoint = null;
	@Override
	protected void onDraw(Canvas canvas) {

		drawNinePoint(canvas);

		super.onDraw(canvas);
	}
	/**
	 * 
	 * @param canvas
	 */
	private void drawNinePoint(Canvas canvas) {

		if (startPoint != null) {
			drawEachLine(canvas, startPoint);
		}

		for(PointInfo pointInfo : points) {
			if (pointInfo!=null) {
				
				if (pointInfo.isSelected()) {			
					canvas.drawBitmap(selectedBitmap, pointInfo.getSeletedX(),pointInfo.getSeletedY(), null);
				}
				canvas.drawBitmap(defaultBitmap, pointInfo.getDefaultX(),pointInfo.getDefaultY(), null);
			}
		}

	}
	private void drawEachLine(Canvas canvas, PointInfo point) {
		if (point.hasNextId()) {
			int n = point.getNextId();
			drawLine(canvas, point.getCenterX(), point.getCenterY(),
					points[n].getCenterX(), points[n].getCenterY());
			drawEachLine(canvas, points[n]);
		}
	}

	private void drawLine(Canvas canvas, float startX, float startY,
			float stopX, float stopY) {
		canvas.drawLine(startX, startY, stopX, stopY, linePaint);
		canvas.drawLine(startX, startY, stopX, stopY, whiteLinePaint);
	}
/**
 * ********************************************************************
 */
	boolean isUp = false;
	int moveX, moveY;
	@Override
	public boolean onTouchEvent(MotionEvent event) {

		boolean flag = true;
		//isUp默认是false--绘制是否完毕,此时为true
		if (isUp) {
			finishDraw();

			Toast.makeText(context, "绘制完毕,手指离开,在点击", 0).show();
			flag = false;

		} else {
			handlingEvent(event);
			flag = true;
			Toast.makeText(context, "手指一旦绘制", 0).show();

		}
		//是否处理事件
		return flag;
	}
	private void finishDraw() {
		for (PointInfo temp : points) {
			temp.setSelected(false);
			temp.setNextId(temp.getId());
		}
		lockString.delete(0, lockString.length());
		isUp = false;
		invalidate();
	}

	private void handlingEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_MOVE:
			moveX = (int) event.getX();
			moveY = (int) event.getY();
			for (PointInfo temp : points) {
				if (temp.isInMyPlace(moveX, moveY) && temp.isSelected()==false) {
					temp.setSelected(true);
					startX = temp.getCenterX();
					startY = temp.getCenterY();
					int len = lockString.length();
					if (len != 0) {
						int preId = lockString.charAt(len - 1) - 48;
						points[preId].setNextId(temp.getId());
					}
					lockString.append(temp.getId());
					break;
				}
			}
			invalidate();
			break;

		case MotionEvent.ACTION_DOWN:
			//获取按下的xy坐标
			int downX = (int) event.getX();
			int downY = (int) event.getY();
			for (PointInfo temp : points) {
				//如果符合距离范围内
				if (temp.isInMyPlace(downX, downY)) {
					//将其设置为选中状态
					temp.setSelected(true);
					//将选中的圆点设置为起始位置圆点
					startPoint = temp;
					//将其圆心作为起始点
					startX = temp.getCenterX();
					startY = temp.getCenterY();
					lockString.append(temp.getId());
					break;
				}
			}
			invalidate();
			break;

		case MotionEvent.ACTION_UP:
			startX = startY = moveX = moveY = 0;
			//绘制完毕
			isUp = true;
			invalidate();
			break;
		default:
			break;
		}
	}



	/**
	 * 原点bean
	 */
	private class PointInfo {
		private boolean selected;

		private int id;

		private int nextId;

		private int defaultX;

		private int defaultY;

		private int seletedX;

		private int seletedY;

		public PointInfo(int id, int defaultX, int defaultY, int seletedX,
				int seletedY) {
			this.id = id;
			this.nextId = id;
			this.defaultX = defaultX;
			this.defaultY = defaultY;
			this.seletedX = seletedX;
			this.seletedY = seletedY;
		}

		public boolean isSelected() {
			return selected;
		}

		public void setSelected(boolean selected) {
			this.selected = selected;
		}

		public int getId() {
			return id;
		}

		public int getDefaultX() {
			return defaultX;
		}

		public int getDefaultY() {
			return defaultY;
		}

		public int getSeletedX() {
			return seletedX;
		}

		public int getSeletedY() {
			return seletedY;
		}

		public int getCenterX() {
			return seletedX + selectedBitmapRadius;
		}

		public int getCenterY() {
			return seletedY + selectedBitmapRadius;
		}

		public boolean hasNextId() {
			return nextId != id;
		}

		public int getNextId() {
			return nextId;
		}

		public void setNextId(int nextId) {
			this.nextId = nextId;
		}

		/**
		 * 如果某个xy值在某个原点的左右上下范围内,就说明ok
		 */
		public boolean isInMyPlace(int x, int y) {
			boolean inX = x > seletedX
					&& x < (seletedX + selectedBitmapDiameter);
			boolean inY = y > seletedY
					&& y < (seletedY + selectedBitmapDiameter);

			return (inX && inY);
		}

	}

}


手势密码(一)

标签:touchevent motionev   九宫格 密码锁   

原文地址:http://blog.csdn.net/u013210620/article/details/46457861

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!