【Android】九宫格手势锁简单实现
现在好多应用都可以设置手势锁,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
相关推荐
- 分布式锁简单入门以及三种实现方式介绍
- android 实现简单的引导层图层功能
- 安卓开发学习笔记(五):史上最简单且华丽地实现Android Stutio当中Webview控件https/http协议的方法...
- redis分布式锁实现高并发简单例子
- Android自定义View——简单实现边缘凹凸电子票效果
- Android 实现 WheelView,这个可以实现类似密码锁的无限轮滑
- Android平台Camera实时滤镜实现方法探讨(八)--滤镜基本制作方法(二)简单美颜滤镜
- 走近Android -R 11 手势的详细设计与实现源码分析
- android手势实现图片的拖动和缩放效果
- 关于局域网内,超简单实现电脑与Android设备的文件传输。
- scroll-view横向滚动无效
- 简单手势识别(特征点定位、Track+Detection、Dlib+Opencv_contrib)