现在好多应用都可以设置手势锁,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 类(存储圆点的信息)

[java]  view plain  copy  print ?
  1. package com.example.mummyding.sudokulock;  
  2.   
  3. /** 
  4.  * Created by mummyding on 15-7-17. 
  5.  */  
  6. public class Cell {  
  7.     private int x;  
  8.     private int y;  
  9.     private boolean isSelected;  
  10.   
  11.     public boolean isSelected() {  
  12.         return isSelected;  
  13.     }  
  14.   
  15.     public void setIsSelected(boolean isSelected) {  
  16.         this.isSelected = isSelected;  
  17.     }  
  18.   
  19.     public int getX() {  
  20.         return x;  
  21.     }  
  22.   
  23.     public void setX(int x) {  
  24.         this.x = x;  
  25.     }  
  26.   
  27.     public int getY() {  
  28.         return y;  
  29.     }  
  30.   
  31.     public void setY(int y) {  
  32.         this.y = y;  
  33.     }  
  34. }  

自定义View

[java]  view plain  copy  print ?
  1. package com.example.mummyding.sudokulock;  
  2.   
  3. import android.app.Notification;  
  4. import android.content.Context;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Color;  
  7. import android.graphics.Paint;  
  8. import android.util.AttributeSet;  
  9. import android.util.DisplayMetrics;  
  10. import android.util.Log;  
  11. import android.view.MotionEvent;  
  12. import android.view.View;  
  13. import android.view.WindowManager;  
  14. import android.widget.Toast;  
  15.   
  16. import java.lang.reflect.Type;  
  17.   
  18. /** 
  19.  * Created by mummyding on 15-7-17. 
  20.  */  
  21. public class SudokuView extends View {  
  22.   
  23.     private static final int COUNT = 3;  
  24.     Cell [] cell;  
  25.     int [] selectedCell;  
  26.     int RADIUS ,OFFSET;  
  27.     int ScreenWidth,ScreenHeight;  
  28.     int startX,startY,selectedCount,lastX,lastY;  
  29.     boolean drawFinish ;  
  30.   
  31.     Paint mPaint ;  
  32.   
  33.   
  34.     public SudokuView(Context context, AttributeSet attrs) {  
  35.         super(context, attrs);  
  36.        init(context);  
  37.   
  38.     }  
  39.   
  40.     private void initCell(){  
  41.         //初始化各点  
  42.         for(int i = 0 ; i < COUNT ; i++ )  
  43.             for (int j = 0 ; j < COUNT ; j++) {  
  44.                 cell[i * COUNT + j].setIsSelected(false);  
  45.                 cell[i * COUNT + j].setX(startX + OFFSET * j - RADIUS/2);  
  46.                 cell[i * COUNT + j].setY(startY + OFFSET * i - RADIUS/2);  
  47.             }  
  48.     }  
  49.     private void init(Context context){  
  50.   
  51.         cell = new Cell[COUNT * COUNT];  
  52.         selectedCell = new int[COUNT*COUNT];  
  53.         mPaint = new Paint();  
  54.         //获取屏幕的宽度和高度  
  55.         WindowManager manager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);  
  56.         DisplayMetrics dm=new DisplayMetrics();  
  57.         manager.getDefaultDisplay().getMetrics(dm);  
  58.   
  59.         ScreenWidth = dm.widthPixels;  
  60.         ScreenHeight = dm.heightPixels;  
  61.   
  62.   
  63.         this.setMinimumWidth(ScreenWidth);  
  64.         this.setMinimumHeight(ScreenHeight);  
  65.   
  66.         drawFinish = false//是否绘制完成  
  67.         selectedCount = 0//已经选中的点个数  
  68.         RADIUS = ScreenWidth / 12//半径  
  69.         OFFSET = ScreenWidth / 4 ; //点之间的间距  
  70.         startX = OFFSET; //起始点横坐标  
  71.         startY = (ScreenHeight - OFFSET * 2) / 2//起始点纵坐标  
  72.   
  73.         for(int i = 0 ; i < COUNT*COUNT ; i++){  
  74.             cell[i] = new Cell();  
  75.         }  
  76.         initCell();  
  77.     }  
  78.   
  79.     int inWhichCircle(int x, int y){  
  80.         for(int i = 0 ; i < COUNT*COUNT ; i++){  
  81.             if(cell[i].isSelected() == false){  
  82.                 if((Math.abs(x - cell[i].getX())
  83.                     return i;  
  84.                 }  
  85.             }  
  86.         }  
  87.         return -1;  
  88.     }  
  89.   
  90.     void drawCell(Canvas canvas){  
  91.        for(int i = 0 ; i < COUNT*COUNT ; i++){  
  92.             //选择画笔&&画圆  
  93.             if(cell[i].isSelected()){  
  94.                 mPaint.setColor(Color.GREEN);  
  95.                 mPaint.setStrokeWidth(10);  
  96.                 //画圆  
  97.                 canvas.drawCircle(cell[i].getX(),cell[i].getY(),RADIUS,mPaint);  
  98.                 mPaint.setStrokeWidth(20);  
  99.                 //画点  
  100.                 canvas.drawPoint(cell[i].getX(),cell[i].getY(),mPaint);  
  101.             } else {  
  102.                 mPaint.setColor(Color.WHITE);  
  103.                 mPaint.setStrokeWidth(5);  
  104.                 //画圆  
  105.                 canvas.drawCircle(cell[i].getX(),cell[i].getY(),RADIUS,mPaint);  
  106.                 //画点  
  107.                 canvas.drawPoint(cell[i].getX(),cell[i].getY(),mPaint);  
  108.             }  
  109.   
  110.         }  
  111.     }  
  112.   
  113.     void drawLine(Canvas canvas) {  
  114.         mPaint.setColor(Color.GREEN);  
  115.         mPaint.setStrokeWidth(5);  
  116.         for(int i = 1 ; i < selectedCount ; i++){  
  117.             Cell lastCell = cell[selectedCell[i-1]],thisCell = cell[selectedCell[i]];  
  118.             canvas.drawLine(lastCell.getX(), lastCell.getY(), thisCell.getX(), thisCell.getY(), mPaint);  
  119.         }  
  120.         if(selectedCount !=0 &&(lastX !=0 || lastY != 0)){  
  121.             canvas.drawLine(cell[selectedCell[selectedCount - 1]].getX(), cell[selectedCell[selectedCount - 1]].getY(), lastX, lastY, mPaint);  
  122.         }  
  123.     }  
  124.   
  125.     @Override  
  126.     protected void onDraw(Canvas canvas) {  
  127.         super.onDraw(canvas);  
  128.         mPaint = new Paint();  
  129.         mPaint.setStrokeWidth(5);;  
  130.         mPaint.setAntiAlias(true);  
  131.         mPaint.setColor(Color.GRAY);  
  132.         mPaint.setStyle(Paint.Style.FILL);  
  133.         mPaint.setStyle(Paint.Style.STROKE);  
  134.         drawCell(canvas);  
  135.         drawLine(canvas);  
  136.     }  
  137.   
  138.   
  139.   
  140.     @Override  
  141.     public boolean onTouchEvent(MotionEvent event) {  
  142.         int tmpIndex;  
  143.         switch (event.getAction()){  
  144.             case MotionEvent.ACTION_DOWN:  
  145.                 drawFinish = false;  
  146.                 if((tmpIndex = inWhichCircle((int)event.getX(),(int)event.getY())) != -1){  
  147.                     cell[tmpIndex].setIsSelected(true);  
  148.                     selectedCell[selectedCount++] = tmpIndex;  
  149.                     this.postInvalidate();  
  150.                 }  
  151.                 break;  
  152.             case MotionEvent.ACTION_MOVE:  
  153.                   if(drawFinish == false){  
  154.                     if((tmpIndex = inWhichCircle((int)event.getX(),(int)event.getY())) != -1){  
  155.                         cell[tmpIndex].setIsSelected(true);  
  156.                         selectedCell[selectedCount++] = tmpIndex;  
  157.                     }  
  158.                 }  
  159.                 lastX = (int) event.getX();  
  160.                 lastY = (int) event.getY();  
  161.                 this.postInvalidate();  
  162.                 break;  
  163.             case MotionEvent.ACTION_UP:  
  164.   
  165.                 drawFinish = true;  
  166.                 lastX = lastY = 0;  
  167.                 selectedCount = 0;  
  168.                 initCell();  
  169.                 this.postInvalidate();  
  170.                 break;  
  171.   
  172.         }  
  173.         return true;  
  174.     }  
  175. }  

布局布局[XML]

[java]  view plain  copy  print ?
  1. "http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"  
  3.     android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"  
  4.     android:background="@color/material_blue_grey_800"  
  5.     android:paddingRight="@dimen/activity_horizontal_margin"  
  6.     android:paddingTop="@dimen/activity_vertical_margin"  
  7.     android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">  
  8.   
  9.     
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         />  
  13.   


完整代码 : https://github.com/MummyDing/SudokuLock


【转载请注明出处】

Author: MummyDing

出处:http://blog.csdn.net/mummyding/article/details/

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. python list.sort()根据多个关键字排序的方法实现
  3. android EditText设置不可写
  4. Android(安卓)拨号器的简单实现
  5. android实现字体闪烁动画的方法
  6. Android(安卓)matrix 控制图片的旋转、缩放、移动
  7. Android中dispatchDraw分析
  8. Android中不同应用间实现SharedPreferences数据共享
  9. 锁屏界面

随机推荐

  1. Android 定位当前位置可能出现的问题
  2. android 开发中遇到的问题
  3. Android style 的继承
  4. java android(ios)通用aes加密解密
  5. Android "多方向"抽屉
  6. Android实现录屏和截屏功能
  7. android:documentLaunchMode
  8. Android上安装lighttpd+php+mysql
  9. android中的EditView控件
  10. Android学习笔记_12_网络通信之从web获取