最近因为项目需要用到九宫格密码(也叫手势轨迹密码),特地去学习了一下九宫格密码的实现原来。可能有人认为九宫格密码事例网上到处都有,很多甚至直接拷贝过来就可以运行为什么还要学习呢。还特地写到网上有必要吗?其实写这个目的是为了增强和锻炼自己的语言组织能力。其实如果只是既然是学习就不光是要知道答案(完成效果)更重要的是知道他什么实现。
好了题外话就不多说了,要实现九宫格密码要解决的问题有:
1,给九宫格密码界面布局九个点,即确定每个节点的位置。每个点到上下左右的距离都是相同的。即九个点刚好围成一个正方形。所以这样的布局界面无法用现有的五大布局来完成必须自定义这个控件。
2,每个节点只能被选择一次,所以必须记录每个点的选中状态。
3,手势开始滑动时,每个节点如何知道手势运动的轨迹经过自己。
4,连线,连线如果步考虑效果,直接用canvas的drawline方法来画连线时当然是很简单的。但是如果用图线(即联系用用一个Bitmap)来画,如何画。解决了这四个问题我们就可以做九宫格密码了。
5,记录被选择节点的顺序。
带着这是那个问题我们开始实现我们要实现的效果。因为网上好多事例所以我就直接拿别人的事例来消化吧。为了更好的解读这个问题我先把代码贴出来后面在讲解这样我觉得我会刚好说一些,大家也更容易理解一些
package org.demo.custon_view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
/**
* @Title: SquaredPassWord.java
* @Description: 九宫格密码
* @author lhz
* @date 2013年9月16日 下午3:48:10
* @version V1.0 Copyright (c) 2013 Company,Inc. All Rights Reserved.
*
*/
public class SquaredPassWord extends View {
ImageView i;
private int length;// 九宫格密码是正方形所以只要知道边长就可以
private Point[] points = new Point[9];// 九宫格节点
private Bitmap defualtPointMap = BitmapFactory.decodeResource(getResources(), R.drawable.locus_round_original);// 正常情况下点的位图
private int poitleght = defualtPointMap.getWidth();// 节点的边长;这里值考虑正方形状态
private Bitmap selectPointMap = BitmapFactory.decodeResource(getResources(), R.drawable.locus_round_click);// 选中情况下点的位图
private Point startPoint;// 起点
private Point tempPoint;// 临时存储上一个节点
private StringBuffer passWBuffer = new StringBuffer();// 保存轨迹顺序的密码
private Bitmap lineBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.locus_line);
private int lineBitmapheight = lineBitmap.getHeight();
private double lineBitmapWidth = lineBitmap.getWidth();
// 以下四个变量是为了绘制最后一个跟手指之间的连线
private int startX;// 移动起点X
private int startY;// 移动起点Y
private int moveX;// 正在移动的X
private int moveY;// 正在移动的Y
public SquaredPassWord(Context context) {
super(context);
}
public SquaredPassWord(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquaredPassWord(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean flag = true;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
passWBuffer.delete(0, passWBuffer.length());
int x = (int) event.getX();
int y = (int) event.getY();
for (Point point : points) {
if (point.isInMyArea(x, y)) {
point.setSelected(true);
tempPoint = startPoint = point;
startX = startPoint.getCenterX();
startY = startPoint.getCenterY();
passWBuffer