涉及到的技术:
自定义控件
数据算法
实现原理:
自定义一个view,里面画九个不同的点,同时监听手指的触摸事件,并且将触摸的点的坐标记录和设置的记录比较一下,如果一致整验证成功,否则验证失败。
自定义控件
1.将9个点画在屏幕的中间。我这边采用的是(高度-宽度)/2---作为便宜量,里面是一个4*4的正方行,依次画出九个点
代码如下:
offset=(height-width)/2;
space=width/4;
points[0][0]=new Point(space,offset+space);
points[0][1]=new Point(space*2,offset+space);
points[0][2]=new Point(space*3,offset+space);
points[1][0]=new Point(space,offset+space*2);
points[1][1]=new Point(space*2,offset+space*2);
points[1][2]=new Point(space*3,offset+space*2);
points[2][0]=new Point(space,offset+space*3);
points[2][1]=new Point(space*2,offset+space*3);
points[2][2]=new Point(space*3,offset+space*3);
2.根据坐标画圆(注意要减去图片的一半,偏移量)
for (int i=0;i<points.length;i++){ for (int j=0;j<points[i].length;j++){ if(points[i][j].state==Point.point_normal){ canvas.drawBitmap(normal,points[i][j].x-normal.getHeight()/2,points[i][j].y-normal.getHeight()/2,paint); }else if(points[i][j].state ==Point.point_press){ canvas.drawBitmap(press,points[i][j].x-normal.getHeight()/2,points[i][j].y-normal.getHeight()/2,paint); }else if(points[i][j].state ==Point.point_error){ canvas.drawBitmap(error,points[i][j].x-normal.getHeight()/2,points[i][j].y-normal.getHeight()/2,paint); } } }
3.触摸事件的处理,需要重写view中的onTouchEvent方法 主要是处理点击,移动和抬起事件 。里面涉及到一个选点的方法,我在point这个实体中添加了一个测量两个点之间的距离的方法,用于判断触摸点的位 置。
public boolean onTouchEvent(MotionEvent event) {
motionX=event.getX();
motionY=event.getY();
int[] result;
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
reset();
result=getSelectedPoint();
if(result!=null){
isDraw=true;
points[result[0]][result[1]].state=Point.point_press;
selectPoint.add(points[result[0]][result[1]]);
password.add(result[0]*3+result[1]);
}
break;
case MotionEvent.ACTION_MOVE:
if(isDraw){
result=getSelectedPoint();
if(result!=null){
if(!selectPoint.contains(points[result[0]][result[1]])){
points[result[0]][result[1]].state=Point.point_press;
selectPoint.add(points[result[0]][result[1]]);
password.add(result[0]*3+result[1]);
}
}
}
break;
case MotionEvent.ACTION_UP:
boolean flag=false;
if(listener!=null&&isDraw){
flag=listener.onFinishedListener(password);
}
if(!flag){
for (int i=0;i<selectPoint.size();i++){
selectPoint.get(i).state=Point.point_error;
}
}
isDraw=false;
break;
}
this.postInvalidate();
return true;
}
4.连接触摸的点涉及到一个划线的方法
private void drawLine(Canvas canvas,Point a,Point b){ if(a.state==Point.point_press){ canvas.drawLine(a.x,a.y,b.x,b.y,pressPaint); } if(a.state==Point.point_error){ canvas.drawLine(a.x,a.y,b.x,b.y,errorPaint); } }
5.重置功能的实现
public void reset(){ selectPoint.clear(); password.clear(); for(int i=0;i<points.length;i++){ for (int j=0;j<points[i].length;j++){ points[i][j].state=Point.point_normal; } } this.postInvalidate(); }
6.向外提供接口的实现
private OnDrawFinishedListener listener; public interface OnDrawFinishedListener{ public boolean onFinishedListener(ArrayList<Integer> pass); } public void setOnDrawFinishedListerer(OnDrawFinishedListener listener){ this.listener=listener; }
这样自定义的锁的界面基本实现了。
里面需要主要的一些细节:
1.初始化的时候只能初始化一边,要不就没有效果出现
2.重置功能一定要调用重绘函数
3.划线的时候注意点位置的变化。
其他我就不介绍了。