现在好多应用都可以设置手势锁,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/



更多相关文章

  1. Android 基础:常用布局 介绍 & 使用(附 属性查询)
  2. android:scaleType="matrix"布局文件加载图片时候的显示方式
  3. Android的XML布局文件中layout_width和width的区别
  4. Android 开发中 布局加载的原理
  5. 全屏显示布局随机图片的显示
  6. Android 自定义布局的Toast

随机推荐

  1. Android(安卓)控件布局常用属性
  2. Android如日中天,学会android,高薪不再愁
  3. android demo
  4. 安卓资源及学习文档
  5. Android属性
  6. Android(安卓)动画
  7. Android(安卓)ScrollView去掉滚动条及Scr
  8. Android实时获得周围wifi信息(SSID,强度等)
  9. Android热点回顾第六期
  10. Android(安卓)Studio学习1——初始Androi