現在好多應用都可以設置手勢鎖,Android本身也有提供手勢圖案鎖屏。作爲Android菜鳥的我,也忍不住想自己動手實現一下。
下面是應用效果圖:
思路:
1.自定義一個View,重寫onDraw方法,利用canvas繪製圖形。
2.實現onTouch事件
* Down Move Down 每次判斷是否有在手指的位置相應處理。
3.直接在佈局文件裏面 引用View就可以了。
注意:
1.我在實現的過程中遇到一個問題,導致應用奔潰,日誌信息也看不懂。最後是在stackoverflow上找到解決方法的。自定義的View一定要實現 兩個參數的構造函數(即 SudokuView(Context context, AttributeSet attrs) )
2.onTouchEvent 方法的返回值一定要是 true,不然就無法相應 Move 和Up 事件了【只會鳥Down~】
下面直接上代碼
Cell 類(存儲圓點的信息)
package com.example.mummyding.sudokulock;
/**
* Created by mummyding on 15-7-17.
*/
public class Cell {
private int x;
private int y;
private boolean isSelected;
public boolean isSelected() {
return isSelected;
}
public void setIsSelected(boolean isSelected) {
this.isSelected = isSelected;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
自定義View
package com.example.mummyding.sudokulock;
import android.app.Notification;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import java.lang.reflect.Type;
/**
* Created by mummyding on 15-7-17.
*/
public class SudokuView extends View {
private static final int COUNT = 3;
Cell [] cell;
int [] selectedCell;
int RADIUS ,OFFSET;
int ScreenWidth,ScreenHeight;
int startX,startY,selectedCount,lastX,lastY;
boolean drawFinish ;
Paint mPaint ;
public SudokuView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void initCell(){
//初始化各點
for(int i = 0 ; i < COUNT ; i++ )
for (int j = 0 ; j < COUNT ; j++) {
cell[i * COUNT + j].setIsSelected(false);
cell[i * COUNT + j].setX(startX + OFFSET * j - RADIUS/2);
cell[i * COUNT + j].setY(startY + OFFSET * i - RADIUS/2);
}
}
private void init(Context context){
cell = new Cell[COUNT * COUNT];
selectedCell = new int[COUNT*COUNT];
mPaint = new Paint();
//獲取屏幕的寬度和高度
WindowManager manager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm=new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(dm);
ScreenWidth = dm.widthPixels;
ScreenHeight = dm.heightPixels;
this.setMinimumWidth(ScreenWidth);
this.setMinimumHeight(ScreenHeight);
drawFinish = false; //是否繪製完成
selectedCount = 0; //已經選中的點個數
RADIUS = ScreenWidth / 12; //半徑
OFFSET = ScreenWidth / 4 ; //點之間的間距
startX = OFFSET; //起始點橫座標
startY = (ScreenHeight - OFFSET * 2) / 2; //起始點縱座標
for(int i = 0 ; i < COUNT*COUNT ; i++){
cell[i] = new Cell();
}
initCell();
}
int inWhichCircle(int x, int y){
for(int i = 0 ; i < COUNT*COUNT ; i++){
if(cell[i].isSelected() == false){
if((Math.abs(x - cell[i].getX())<RADIUS) && Math.abs(y - cell[i].getY()) < RADIUS){
return i;
}
}
}
return -1;
}
void drawCell(Canvas canvas){
for(int i = 0 ; i < COUNT*COUNT ; i++){
//選擇畫筆&&畫圓
if(cell[i].isSelected()){
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(10);
//畫圓
canvas.drawCircle(cell[i].getX(),cell[i].getY(),RADIUS,mPaint);
mPaint.setStrokeWidth(20);
//畫點
canvas.drawPoint(cell[i].getX(),cell[i].getY(),mPaint);
} else {
mPaint.setColor(Color.WHITE);
mPaint.setStrokeWidth(5);
//畫圓
canvas.drawCircle(cell[i].getX(),cell[i].getY(),RADIUS,mPaint);
//畫點
canvas.drawPoint(cell[i].getX(),cell[i].getY(),mPaint);
}
}
}
void drawLine(Canvas canvas) {
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(5);
for(int i = 1 ; i < selectedCount ; i++){
Cell lastCell = cell[selectedCell[i-1]],thisCell = cell[selectedCell[i]];
canvas.drawLine(lastCell.getX(), lastCell.getY(), thisCell.getX(), thisCell.getY(), mPaint);
}
if(selectedCount !=0 &&(lastX !=0 || lastY != 0)){
canvas.drawLine(cell[selectedCell[selectedCount - 1]].getX(), cell[selectedCell[selectedCount - 1]].getY(), lastX, lastY, mPaint);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint = new Paint();
mPaint.setStrokeWidth(5);;
mPaint.setAntiAlias(true);
mPaint.setColor(Color.GRAY);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStyle(Paint.Style.STROKE);
drawCell(canvas);
drawLine(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int tmpIndex;
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
drawFinish = false;
if((tmpIndex = inWhichCircle((int)event.getX(),(int)event.getY())) != -1){
cell[tmpIndex].setIsSelected(true);
selectedCell[selectedCount++] = tmpIndex;
this.postInvalidate();
}
break;
case MotionEvent.ACTION_MOVE:
if(drawFinish == false){
if((tmpIndex = inWhichCircle((int)event.getX(),(int)event.getY())) != -1){
cell[tmpIndex].setIsSelected(true);
selectedCell[selectedCount++] = tmpIndex;
}
}
lastX = (int) event.getX();
lastY = (int) event.getY();
this.postInvalidate();
break;
case MotionEvent.ACTION_UP:
drawFinish = true;
lastX = lastY = 0;
selectedCount = 0;
initCell();
this.postInvalidate();
break;
}
return true;
}
}
佈局佈局[XML]
<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:background="@color/material_blue_grey_800"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<com.example.mummyding.sudokulock.SudokuView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
完整代碼 : https://github.com/MummyDing/SudokuLock
【轉載請註明出處】
Author: MummyDing
出處:http://blog.csdn.net/mummyding/article/details/