码迷,mamicode.com
首页 > 移动开发 > 详细

【Android】九宫格手势锁简单实现

时间:2015-07-18 12:39:47      阅读:329      评论:0      收藏:0      [点我收藏+]

标签:android   九宫格手势   自定义view   

现在好多应用都可以设置手势锁,Android本身也有提供手势图案锁屏。作为Android菜鸟的我,也忍不住想自己动手实现一下。

下面是应用效果图:

技术分享



思路:

1.自定义一个View,重写onDraw方法,利用canvas绘制图形。

2.实现onTouch事件

* Down Move Down  每次判断是否有在手指的位置相应处理。

3.直接在布局文件里面 引用View就可以了。

注意:

我在实现的过程中遇到一个问题,导致应用奔溃,日志信息也看不懂。最后是在stackoverflow上找到解决方法的。自定义的View一定要实现 两个参数的构造函数(即 SudokuView(Context context, AttributeSet attrs) )


下面直接上代码

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/



版权声明:本文为博主原创文章,未经博主允许不得转载。

【Android】九宫格手势锁简单实现

标签:android   九宫格手势   自定义view   

原文地址:http://blog.csdn.net/mummyding/article/details/46940151

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!