一個手勢圖案解鎖的小demo
有些應用為了安全加個圖案解鎖也不錯,下面是圖案解鎖的小demo
主要涉及到View的自定義,線、圓的繪製,以及touch事件的處理,有需要的可以參考下。
主要步驟:
1.繪製9個觸點
2.繪製連線線,觸點選中狀態
3.繪製驗證出錯時狀態
說明:
1.其中涉及的(x,y)座標都是相對於當前View的左上角(0,0)而言;
2.TextView在繪製時,是從文字的左下角開始繪製的
Touch事件處理如下:
@Override
public boolean onTouchEvent(MotionEvent event) {
float crtX = event.getX();//57.79834
float crtY = event.getY();//40.588318
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isUp = false;
Log.e("--Action--Down", "--Action--Down");
int index = getItemIndex(crtX, crtY);
if(index >= 0){
int row = index / 3; //當前行
int column = index % 3;//當前列
int crtCenterX = column * (radius + padding) * 2 + padding + radius;
int crtCenterY = row * (radius * 2 + padding * 2) + padding + radius;
drawStartX = crtCenterX;
drawStartY = crtCenterY;
drawEndX = crtCenterX;
drawEndY = crtCenterY;
isDrawStart = true;
}
break;
case MotionEvent.ACTION_UP:
isUp = true;
Log.e("--Action--Up", "--Action--Up");
int lineCount = lineList.size();
if(lineCount > 0
&& !isAtPoint(lineList.get(lineCount - 1).getEndX(), lineList.get(lineCount - 1).getEndY())){
lineList.remove(lineCount - 1);
invalidate();
}
else {
if(verifyTheKey()){
//go to next activity
Log.e("--go--to--next--activity--", "--go--to--next--activity--");
}
else {
pointPaint.setColor(Color.RED);
invalidate();
}
isDrawStart = false;
}
drawStartX= 0;
drawStartY = 0;
drawEndX = 0;
drawEndY = 0;
break;
case MotionEvent.ACTION_MOVE:
if(isDrawStart){
int moveIndex = getItemIndex(crtX, crtY);
//當前位於觸點區域
if(moveIndex >= 0){
int row = moveIndex / 3; //當前行
int column = moveIndex % 3;//當前列
int crtCenterX = column * (radius + padding) * 2 + padding + radius;
int crtCenterY = row * (radius * 2 + padding * 2) + padding + radius;
if(isAtPoint(drawStartX, drawStartY)){//線的起點正在中心點上
if(isPointContains(crtCenterX, crtCenterY)){//已經記錄過此點
drawEndX = crtX;
drawEndY = crtY;
updateLines(true);
return true;
}
if(crtX != crtCenterX || crtY != crtCenterY){//當前位置不在中心點
drawEndX = crtCenterX;
drawEndY = crtCenterY;
itemList.get(moveIndex).setShowPoint(true);//顯示選中狀態
updateLines(true);
drawStartX = drawEndX;
drawStartY = drawEndY;
}
else {//當前位置在中心點
drawStartX = crtCenterX;
drawStartY = crtCenterY;
itemList.get(moveIndex).setShowPoint(true);
updateLines(true);
}
}
}
else {//不在觸點區域
drawEndX = crtX;
drawEndY = crtY;
updateLines(true);
}
}
break;
default:
break;
}
return true;
}
在需要重繪時呼叫invalidate方法,將導致onDraw()方法的執行,從而重新進行View的繪製。view繪製是從裡由外而進行繪製的,因而需要設定好繪製的先後順序。
主要繪製就在onDraw()方法中:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//繪製觸點
drawItem(canvas);
//繪製連線線
for(LineItem line : lineList){
canvas.drawLine(line.getStartX(), line.getStartY(),
line.getEndX(), line.getEndY(), linePaint);
}
if(isUp){
if(isDrawStart){
if(verifyTheKey()){
//go to next activity
Log.e("--go--to--next--activity--", "--go--to--next--activity--");
}
else {
pointPaint.setColor(Color.RED);//驗證未通過,將觸點置為紅色
invalidate();
isDrawStart = false;
}
}
}
}
具體的demo,見: