您的位置:首页 > 其它

手势密码(二)

2015-08-30 12:46 190 查看


代码地址下载

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="请输入密码"
android:id="@+id/text"
/>

<com.example.lockpatterview.LockPatterView
android:id="@+id/lock"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />

</LinearLayout>


MainActivity

package com.example.lockpatterview;

import com.example.lockpatterview.LockPatterView.OnPatterChangeLister;

import android.os.Bundle;
import android.text.TextUtils;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;

public class MainActivity extends Activity implements OnPatterChangeLister {

LockPatterView lock;
TextView text;
String p = "14789";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
lock = (LockPatterView) findViewById(R.id.lock);
lock.SetOnPatterChangeLister(this);
}

@Override
public void onPatterChange(String passwordStr) {
if (!TextUtils.isEmpty(passwordStr)) {
if (passwordStr.equals(p)) {
text.setText(passwordStr);
} else {
text.setText("密码错误");
lock.errorPoint();
}
}else {
Toast.makeText(MainActivity.this, "至少连接5点", 0).show();
}

}

@Override
public void onPatterStart(boolean isStart) {
if (isStart) {
text.setText("请绘制图案");
}
}

}


LockPatterView

package com.example.lockpatterview;

import java.util.ArrayList;
import java.util.List;

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.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class LockPatterView extends View {

private static final int POINT_SIZE = 5;

private Point[][] points = new Point[3][3];

private Matrix matrix = new Matrix();

private float width, height, offstartY, moveX, moveY;;

private Bitmap bitmap_pressed, bitmap_normal, bitmap_error, bitmap_line,
bitmap_line_error;

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

private List<Point> pointList = new ArrayList<LockPatterView.Point>();

private OnPatterChangeLister onPatterChangeLister;

/**
* 构造函数
*/
public LockPatterView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

public LockPatterView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public LockPatterView(Context context) {
super(context);
}

/*********************************************************
* 绘制9宫格
* movePoint代表鼠标在移动,但是不是9宫格里面的点
* isInit是否初始化过9个点
* isSelect 点位是否被选中状态
* isFinish 是否绘制完毕
*/
private boolean isInit, isSelect, isFinish, movePoint;

@Override
protected void onDraw(Canvas canvas) {
// 第一次没有初始化就进行初始化,一旦初始化就不在初始化工作了,isInit的意思是---默认没有初始化过
if (!isInit) {
// 初始化9个点
initPoints();
}
// 绘制9个点
points2Canvas(canvas);

if (pointList.size() > 0) {
Point a = pointList.get(0);
// 绘制九宫格坐标点
for (int i = 0; i < pointList.size(); i++) {
Point b = pointList.get(i);
line2Canvas(canvas, a, b);
a = b;
}
// 绘制鼠标坐标点
if (movePoint) {
line2Canvas(canvas, a, new Point(moveX, moveY));
}
}
}

/**
* 初始化9个点位 获取点位的3种状态 线的2种状态 以及9点的坐标位置 以及初始化密码操作 isInit=
* true设置状态--下次不必初始化话工作了
*/
private void initPoints() {

// 获取布局宽高
width = getWidth();
height = getHeight();

// 横屏和竖屏

offstartY = (height - width) / 2;

// 图片资源
bitmap_normal = BitmapFactory.decodeResource(getResources(),
R.drawable.btn_circle_normal);
bitmap_pressed = BitmapFactory.decodeResource(getResources(),
R.drawable.btn_circle_pressed);
bitmap_error = BitmapFactory.decodeResource(getResources(),
R.drawable.btn_circle_selected);
bitmap_line = BitmapFactory.decodeResource(getResources(),
R.drawable.ddd);
bitmap_line_error = BitmapFactory.decodeResource(getResources(),
R.drawable.qqq);

points[0][0] = new Point(width / 4, offstartY + width / 4);
points[0][1] = new Point(width / 2, offstartY + width / 4);
points[0][2] = new Point(width / 4 * 3, offstartY + width / 4);

points[1][0] = new Point(width / 4, offstartY + width / 4 * 2);
points[1][1] = new Point(width / 2, offstartY + width / 4 * 2);
points[1][2] = new Point(width / 4 * 3, offstartY + width / 4 * 2);

points[2][0] = new Point(width / 4, offstartY + width / 4 * 3);
points[2][1] = new Point(width / 2, offstartY + width / 4 * 3);
points[2][2] = new Point(width / 4 * 3, offstartY + width / 4 * 3);

// 设置密码1--9
int index = 1;
for (Point[] points : this.points) {
for (Point point : points) {
point.index = index;
index++;
}
}
// 初始化完成
isInit = true;
}

/**
* 将9个点绘制到画布 循环遍历9个点位, 根据3种不同的状态绘制3种不同的9个点位
*/
private void points2Canvas(Canvas canvas) {
// 循环遍历9个点位
for (int i = 0; i < points.length; i++) {
// 循环遍历每行的3个点位
for (int j = 0; j < points[i].length; j++) {
// 获取依次的某个点位
Point point = points[i][j];
if (point.state == Point.STATE_PRESSED) {
// (Bitmap bitmap, float left, float top, Paint paint)
canvas.drawBitmap(bitmap_pressed,
point.x - bitmap_normal.getWidth() / 2, point.y
- bitmap_normal.getHeight() / 2, paint);
} else if (point.state == Point.STATE_ERROR) {
canvas.drawBitmap(bitmap_error,
point.x - bitmap_normal.getWidth() / 2, point.y
- bitmap_normal.getHeight() / 2, paint);
} else {
canvas.drawBitmap(bitmap_normal,
point.x - bitmap_normal.getWidth() / 2, point.y
- bitmap_normal.getHeight() / 2, paint);
}
}
}
}

/**
* 画线
*/
public void line2Canvas(Canvas canvas, Point a, Point b) {
// 线的长度--2点之间的距离
float linelength = (float) Point.distance(a, b);
// 获取2点之间的角度
float degress = getDegrees(a, b);
//根据a点进行旋转
canvas.rotate(degress, a.x, a.y);

if (a.state == Point.STATE_PRESSED) {
// xy方向上的缩放比例
matrix.setScale(linelength / bitmap_line.getWidth(), 1);
matrix.postTranslate(a.x - bitmap_line.getWidth() / 2, a.y
- bitmap_line.getHeight() / 2);
canvas.drawBitmap(bitmap_line, matrix, paint);
} else {
matrix.setScale(linelength / bitmap_line.getWidth(), 1);
matrix.postTranslate(a.x - bitmap_line.getWidth() / 2, a.y
- bitmap_line.getHeight() / 2);
canvas.drawBitmap(bitmap_line_error, matrix, paint);
}
//画线完毕回归角度
canvas.rotate(-degress, a.x, a.y);
}

// 获取角度
public float getDegrees(Point pointA, Point pointB) {
return (float) Math.toDegrees(Math.atan2(pointB.y - pointA.y, pointB.x
- pointA.x));
}

/****************************************************************************
* onTouch事件处理
*/

@Override
public boolean onTouchEvent(MotionEvent event) {
moveX = event.getX();
moveY = event.getY();

movePoint = false;
isFinish = false;

Point point = null;

switch (event.getAction()) {
//只要按下操作,就代表重新绘制界面
case MotionEvent.ACTION_DOWN:
if (onPatterChangeLister != null) {
onPatterChangeLister.onPatterStart(true);
}
// 每次按下,都需要清空之前的集合
resetPoint();
// 检测是不是在九宫格内
point = chechSelectPoint();
if (point != null) {
//如果按下的位置在9宫格内,就改成状态为true
isSelect = true;
}
break;
case MotionEvent.ACTION_MOVE:
if (isSelect) {
// 检测是不是在九宫格内
point = chechSelectPoint();
if (point == null) {
movePoint = true;
}
}
break;
case MotionEvent.ACTION_UP:
//绘制完毕,点位状态改为未选中
isFinish = true;
isSelect = false;
break;

}
// 如果没有绘制完毕,如果九宫格处于选中状态
if (!isFinish && isSelect && point != null) {
// 交叉点
if (crossPoint(point)) {
movePoint = true;
} else {// 新点
point.state = Point.STATE_PRESSED;
pointList.add(point);
}
}

// 绘制结束
if (isFinish) {
// 绘制不成立
if (pointList.size() == 1) {
// resetPoint();
errorPoint();
} else if (pointList.size() < POINT_SIZE && pointList.size() > 0) {// 绘制错误
errorPoint();
if (onPatterChangeLister != null) {
onPatterChangeLister.onPatterChange(null);
}
} else {
if (onPatterChangeLister != null) {
String pass = "";
for (int i = 0; i < pointList.size(); i++) {
pass = pass + pointList.get(i).index;
}
if (!TextUtils.isEmpty(pass)) {
onPatterChangeLister.onPatterChange(pass);
}
}
}
}

postInvalidate();
return true;
}

/**
* 重新绘制
*/
public void resetPoint() {
for (int i = 0; i < pointList.size(); i++) {
Point point = pointList.get(i);
point.state = Point.STATE_NORMAL;
}
pointList.clear();
}

/**
* 检查是否选中
*/
private Point chechSelectPoint() {
for (int i = 0; i < points.length; i++) {
for (int j = 0; j < points[i].length; j++) {
Point point = points[i][j];
if (Point.with(point.x, point.y, bitmap_normal.getWidth() / 2,
moveX, moveY)) {
return point;
}
}
}

return null;
}

/**
* 交叉点
*/
private boolean crossPoint(Point point) {
if (pointList.contains(point)) {
return true;
} else {
return false;
}
}

/**
* 绘制错误
*/
public void errorPoint() {
for (Point point : pointList) {
point.state = Point.STATE_ERROR;
}
}

/***********************************************************************
* 自定义的点
*/
public static class Point {
// 正常
public static int STATE_NORMAL = 0;
// 选中
public static int STATE_PRESSED = 1;
// 错误
public static int STATE_ERROR = 2;
public float x, y;
public int index = 0, state = 0;

public Point() {
};

public Point(float x, float y) {
this.x = x;
this.y = y;
}

/**
* 两点之间的距离
*/
public static double distance(Point a, Point b) {
return Math.sqrt(Math.abs(a.x - b.x) * Math.abs(a.x - b.x)
+ Math.abs(a.y - b.y) * Math.abs(a.y - b.y));
}

/**
*/
public static boolean with(float paintX, float pointY, float r,
float moveX, float moveY) {
return Math.sqrt((paintX - moveX) * (paintX - moveX)
+ (pointY - moveY) * (pointY - moveY)) < r;
}
}

/**
* 图案监听器
*/
public static interface OnPatterChangeLister {
void onPatterChange(String passwordStr);

void onPatterStart(boolean isStart);
}

/**
* 设置图案监听器
*/
public void SetOnPatterChangeLister(OnPatterChangeLister changeLister) {
if (changeLister != null) {
this.onPatterChangeLister = changeLister;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: