首页 > 系统 > Android > 正文

Android自定义UI手势密码终结版

2019-12-12 04:51:56
字体:
来源:转载
供稿:网友

之前写过3篇手势密码的demo,不过没有集成到真实的企业项目中,这几天正好领到一个手势密码项目,昨天刚好弄完,今天抽空整理下,目前还没有完善,有一些地方需要更改,不过基本的流程都可以跑通了。

源码下载地址:http://xiazai.VeVB.COm/201610/yuanma/AndroidGestureLock(VeVB.COm).rar

先看主界面的入口把、里面有2个button(一个是设置手势密码、一个是校验手势密码)
activity_main.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"  tools:context="com.example.gesturelock.MainActivity" >   <Button  android:id="@+id/setting"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentLeft="true"  android:layout_alignParentTop="true"  android:text="设置" />   <Button  android:id="@+id/verify"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentTop="true"  android:layout_toRightOf="@+id/setting"  android:text="校验" />  </RelativeLayout> 

在看主界面的代码把
MainActivity

package com.example.gesturelock;  import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;  public class MainActivity extends Activity implements OnClickListener {   private Button setting, verify;   @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  setting = (Button) findViewById(R.id.setting);  verify = (Button) findViewById(R.id.verify);  setting.setOnClickListener(this);  verify.setOnClickListener(this);  }   @Override  public void onClick(View v) {  switch (v.getId()) {  case R.id.setting:    startActivity(new Intent(this, GestureEditActivity.class));   break;  case R.id.verify:   startActivity(new Intent(this, GestureVerifyActivity.class));    break;   default:   break;  }  }  } 

想了想还是先贴数据库把---就是存放手势密码、以及还可以输入的手势密码次数
publicSQLiteOpenHelper

package com.example.gesturelock;  import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper;  public class publicSQLiteOpenHelper extends SQLiteOpenHelper{  private static String name = "publicsqlite";  private static String GESTURE_PASSWORD = "gesture_password";  private static final int version = 1;  public SQLiteDatabase db;   public publicSQLiteOpenHelper(Context context)  {   super(context, name, null, version);  }  @Override  public void onCreate(SQLiteDatabase db)  {    String sqlpass = "create table " + "gesture_password"+ "("    + GesturePassword.WXID + " text not null,"    + GesturePassword.PASSWORD + " text not null,"    + GesturePassword.REMAINOPPORTUNITY + " text not null)";   db.execSQL(sqlpass);  }  @Override  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)  {   db.execSQL("DROP TABLE IF EXISTS password");   onCreate(db);  }    public class GesturePassword  {   public static final String WXID = "wxid";   public static final String PASSWORD = "password";   public static final String REMAINOPPORTUNITY = "remainopportunity";    }       /**   * 插入手势密码表   */  public void insertGestureInfo(SQLiteDatabase database ,String password,String times){   ContentValues values = null;   try {   values = new ContentValues();   values.put(GesturePassword.WXID, "001");   values.put(GesturePassword.PASSWORD, password);   values.put(GesturePassword.REMAINOPPORTUNITY, ""+times);   database.insert(publicSQLiteOpenHelper.GESTURE_PASSWORD, null,    values);      } catch (Exception e) {   e.printStackTrace();   throw new SQLException(e.getMessage());   }finally{   if (values != null) {    values.clear();    values = null;   }   }    }  /**   * 修改手势密码表---初始化次数为8次   *   *   */     public void updateGestureInfo(SQLiteDatabase database,String password,String times) {   ContentValues values = null;      try {       if (password == null) {    values = new ContentValues();    values.put(GesturePassword.WXID, "001");    values.put(GesturePassword.REMAINOPPORTUNITY, ""+times);    database.update(publicSQLiteOpenHelper.GESTURE_PASSWORD,     values, "WXID=?",     new String[] { "001" });        }else {        values = new ContentValues();    values.put(GesturePassword.WXID, "001");    values.put(GesturePassword.PASSWORD, password);    values.put(GesturePassword.REMAINOPPORTUNITY, ""+times);    database.update(publicSQLiteOpenHelper.GESTURE_PASSWORD,     values, "WXID=?",     new String[] { "001" });    }   } catch (SQLException e) {      } finally {    if (values != null) {    values.clear();    values = null;    }   }   }   /**   * 查询手势密码表有无记录   * @return   */   public boolean queryGestureTableCount(SQLiteDatabase database){   Cursor cursor = null;      try {    cursor = database.query(publicSQLiteOpenHelper.GESTURE_PASSWORD, null, null, null, null, null, null);    if (cursor != null && cursor.getCount()>0) {    return true;        }else {    return false;    }      } catch (Exception e) {      }   finally{    if (cursor != null) {    cursor.close();    cursor = null;    }   }   return false;   }     /**   * 查询手势密码表--查看剩余次数   *   */   public String queryGestureTime(SQLiteDatabase database) {   Cursor cursor = null;   try {    cursor = database.query(publicSQLiteOpenHelper.GESTURE_PASSWORD, null, null, null, null, null, null);     if ((cursor != null) && (cursor.getCount() > 0)) {    if (cursor.moveToFirst()) {     int columnIndex = cursor      .getColumnIndex(GesturePassword.REMAINOPPORTUNITY);     return cursor.getString(columnIndex);    }     }   } catch (Exception e) {      } finally {    if (cursor != null) {    cursor.close();    cursor = null;    }   }   return "";   }     /**   * 查询手势密码表--查看密码   *   */   public String queryGesturePassword(SQLiteDatabase database) {   Cursor cursor = null;   try {    cursor = database.query(publicSQLiteOpenHelper.GESTURE_PASSWORD, null, null, null, null, null, null);     if ((cursor != null) && (cursor.getCount() > 0)) {    if (cursor.moveToFirst()) {     int columnIndex = cursor      .getColumnIndex(GesturePassword.PASSWORD);     return cursor.getString(columnIndex);    }     }   } catch (Exception e) {      } finally {    if (cursor != null) {    cursor.close();    cursor = null;    }   }   return "";   } } 

接下里再看工具类把--就是输入的手势密码简单MD5加密、以及屏幕尺寸工具类

/**  *  */ package com.example.gesturelock;  import android.content.Context; import android.view.WindowManager;  public class AppUtil {   /**  * 获取屏幕分辨�?  * @param context  * @return  */  public static int[] getScreenDispaly(Context context) {  WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);  @SuppressWarnings("deprecation")  int width = windowManager.getDefaultDisplay().getWidth();  @SuppressWarnings("deprecation")  int height = windowManager.getDefaultDisplay().getHeight();  int result[] = { width, height };  return result;  }  } 

package com.example.gesturelock;  import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;  import android.util.Log;  public class MD5EncodeUtil {  public static String MD5Ecode(String gesture){  Log.i("GYL","gesture---"+gesture.toString());  byte[] toencode=gesture.toString().getBytes();  Log.i("GYL","byte[]----"+toencode.toString());    try{   MessageDigest md5=MessageDigest.getInstance("MD5");   md5.reset();   md5.update(toencode);   return HexEncode(md5.digest());  }catch(NoSuchAlgorithmException e){   e.printStackTrace();  }  return "";  }  public static String HexEncode(byte[] toencode){  StringBuilder sb=new StringBuilder(toencode.length*2);  for(byte b:toencode){   sb.append(Integer.toHexString((b&0xf0)>>>4));   sb.append(Integer.toHexString(b&0x0f));   }  return sb.toString().toUpperCase();  } } 

一步步来,接下来看bean类,就是每个圆点的属性
Constants

package com.example.gesturelock;  public class Constants {  public static final int POINT_STATE_NORMAL = 0; // 正常状态  public static final int POINT_STATE_SELECTED = 1; // 按下状态  public static final int POINT_STATE_WRONG = 2; // 错误状态  } 

GesturePoint

package com.example.gesturelock;  import android.widget.ImageView;  public class GesturePoint {  /**  * 左边x的值  */  private int leftX;  /**  * 右边x的值  */  private int rightX;  /**  * 上边y的值  */  private int topY;  /**  * 下边y的值  */  private int bottomY;  /**  * 这个点对应的ImageView控件  */  private ImageView image;   /**  * 中心x值  */  private int centerX;   /**  * 中心y值  */  private int centerY;   /**  * 状态值  */  private int pointState;   /**  * 代表这个Point对象代表的数字,从1开始(直接感觉从1开始)  */  private int num;   public GesturePoint(int leftX, int rightX, int topY, int bottomY,   ImageView image, int num) {  super();  this.leftX = leftX;  this.rightX = rightX;  this.topY = topY;  this.bottomY = bottomY;  this.image = image;  this.centerX = (leftX + rightX) / 2;  this.centerY = (topY + bottomY) / 2;  this.num = num;  }   public int getLeftX() {  return leftX;  }   public void setLeftX(int leftX) {  this.leftX = leftX;  }   public int getRightX() {  return rightX;  }   public void setRightX(int rightX) {  this.rightX = rightX;  }   public int getTopY() {  return topY;  }   public void setTopY(int topY) {  this.topY = topY;  }   public int getBottomY() {  return bottomY;  }   public void setBottomY(int bottomY) {  this.bottomY = bottomY;  }   public ImageView getImage() {  return image;  }   public void setImage(ImageView image) {  this.image = image;  }   public int getCenterX() {  return centerX;  }   public void setCenterX(int centerX) {  this.centerX = centerX;  }   public int getCenterY() {  return centerY;  }   public void setCenterY(int centerY) {  this.centerY = centerY;  }   public int getPointState() {  return pointState;  }   public void setPointState(int state, int x, int y) {   pointState = state;  switch (state) {   case Constants.POINT_STATE_NORMAL:   this.image.setBackgroundResource(R.drawable.gesturewhite);   break;  case Constants.POINT_STATE_SELECTED:    // 以原点为圆心,右下为正,左上为负   if (y == 0 && x > 0) {   this.image.setBackgroundResource(R.drawable.blueright);   } else if (y == 0 && x < 0) {   this.image.setBackgroundResource(R.drawable.blueleft);   } else if (x == 0 && y > 0) {   this.image.setBackgroundResource(R.drawable.bluedown);   } else if (x == 0 && y < 0) {   this.image.setBackgroundResource(R.drawable.blueup);   } else if (x > 0 && y > 0) {   this.image.setBackgroundResource(R.drawable.bluerightdown);   } else if (x < 0 && y < 0) {   this.image.setBackgroundResource(R.drawable.blueleftup);   } else if (x < 0 && y > 0) {   this.image.setBackgroundResource(R.drawable.blueleftdown);   } else if (x > 0 && y < 0) {   this.image.setBackgroundResource(R.drawable.bluerightup);   } else if (x == 0 && y == 0) {   this.image.setBackgroundResource(R.drawable.bluedot);   }    break;  case Constants.POINT_STATE_WRONG:    if (y == 0 && x > 0) {   this.image.setBackgroundResource(R.drawable.redright);   } else if (y == 0 && x < 0) {   this.image.setBackgroundResource(R.drawable.redleft);   } else if (x == 0 && y > 0) {   this.image.setBackgroundResource(R.drawable.reddown);   } else if (x == 0 && y < 0) {   this.image.setBackgroundResource(R.drawable.redup);   } else if (x > 0 && y > 0) {   this.image.setBackgroundResource(R.drawable.redrightdown);   } else if (x < 0 && y < 0) {   this.image.setBackgroundResource(R.drawable.redleftup);   } else if (x < 0 && y > 0) {   this.image.setBackgroundResource(R.drawable.redleftdown);   } else if (x > 0 && y < 0) {   this.image.setBackgroundResource(R.drawable.redrightup);   } else if (x == 0 && y == 0) {   this.image.setBackgroundResource(R.drawable.reddot);   }   break;  default:   break;  }  }   public int getNum() {  return num;  }   public void setNum(int num) {  this.num = num;  }   @Override  public int hashCode() {  final int prime = 31;  int result = 1;  result = prime * result + bottomY;  result = prime * result + ((image == null) ? 0 : image.hashCode());  result = prime * result + leftX;  result = prime * result + rightX;  result = prime * result + topY;  return result;  }   @Override  public boolean equals(Object obj) {  if (this == obj)   return true;  if (obj == null)   return false;  if (getClass() != obj.getClass())   return false;  GesturePoint other = (GesturePoint) obj;  if (bottomY != other.bottomY)   return false;  if (image == null) {   if (other.image != null)   return false;  } else if (!image.equals(other.image))   return false;  if (leftX != other.leftX)   return false;  if (rightX != other.rightX)   return false;  if (topY != other.topY)   return false;  return true;  }   @Override  public String toString() {  return "Point [leftX=" + leftX + ", rightX=" + rightX + ", topY="   + topY + ", bottomY=" + bottomY + "]";  } } 

接下来就看那9个点的绘制界面
GestureContentView

package com.example.gesturelock;  import java.util.ArrayList; import java.util.List;  import com.example.gesturelock.GestureDrawline.GestureCallBack;  import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView;   /**  * 手势密码容器类  *  */ public class GestureContentView extends ViewGroup {    /**  * 每个点区域的宽度  */  private int blockWidth;  private int spacing ;   /**  * 声明一个集合用来封装坐标集合  */  private List<GesturePoint> list;  private Context context;  private GestureDrawline gestureDrawline;   /**  * 包含9个ImageView的容器,初始化  * @param context  * @param isVerify 是否为校验手势密码  * @param passWord 用户传入密码  * @param callBack 手势绘制完毕的回调  */  public GestureContentView(Context context, boolean isVerify,String passWord, GestureCallBack callBack) {  super(context);  this.blockWidth = dip2px(context,66f); //圆圈的直径dp值  this.spacing = dip2px(context, 30f); //圆圈之间的距离dp值  this.list = new ArrayList<GesturePoint>();  this.context = context;  // 添加9个图标  addChild();  // 初始化一个可以画线的view  gestureDrawline = new GestureDrawline(context, list, isVerify,passWord, callBack);  }   public static int dip2px(Context context, float dpValue) {  // TODO Auto-generated method stub  final float scale = context.getResources().getDisplayMetrics().density;  return (int) (dpValue * scale + 0.5f);  }   private void addChild(){  for (int i = 0; i < 9; i++) {   ImageView image = new ImageView(context);   image.setBackgroundResource(R.drawable.gesturewhite);    this.addView(image,new LayoutParams(blockWidth, blockWidth));   invalidate();   // 第几行   int row = i / 3;   // 第几列   int col = i % 3;   // 定义点的每个属性   int leftX = col * blockWidth + col * spacing;   int topY = row * blockWidth + row * spacing;   int rightX = leftX + blockWidth;   int bottomY = topY + blockWidth;     //圆圈之间线的位置   GesturePoint p = new GesturePoint(leftX, rightX, topY, bottomY, image,i+1);   this.list.add(p);  }  }   public void setParentView(ViewGroup parent){  // 得到屏幕的宽度  LayoutParams layoutParams =   new LayoutParams(blockWidth * 3 + spacing * 2, blockWidth * 3 + spacing * 2);  parent.addView(gestureDrawline,layoutParams);  parent.addView(this,layoutParams);  }   @Override  protected void onLayout(boolean changed, int l, int t, int r, int b) {  for (int i = 0; i < getChildCount(); i++) {   //第几行   int row = i/3;   //第几列   int col = i%3;   View v = getChildAt(i);   //用于绘制圆圈的位置,d表示X轴方向的偏移量,如果要上下移动整块手绘区域,则将top和bottom参数增加或减小一个合适的偏移量   int leftX = col * blockWidth + col * spacing;   int topY = row * blockWidth + row * spacing;   int rightX = leftX + blockWidth;   int bottomY = topY + blockWidth;     v.layout(leftX, topY, rightX, bottomY) ;  }  }   @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  }   /**  * 保留路径delayTime时间长  * @param delayTime  */  public void clearDrawlineState(long delayTime) {  gestureDrawline.clearDrawlineState(delayTime);  }  } 

然后继续看当手指连接时候,的那个绘制中间连线的代码
GestureDrawline

package com.example.gesturelock;  import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;   import android.annotation.SuppressLint; import android.content.Context;  import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.PorterDuff; import android.os.Handler;  import android.util.Log; import android.util.Pair; import android.view.MotionEvent; import android.view.View;  /**  * 手势密码路径绘制  *  */ public class GestureDrawline extends View {  private int mov_x;// 声明起点坐标  private int mov_y;  private Paint paint;// 声明画笔  private Canvas canvas;// 画布  private Bitmap bitmap;// 位图  private List<GesturePoint> list;//  private List<Pair<GesturePoint, GesturePoint>> lineList;// 记录画过的线  private Map<String, GesturePoint> autoCheckPointMap;// 自动选中的情况点  private boolean isDrawEnable = true; // 是否允许绘制  /**  * 屏幕的宽度和高度  */  private int[] screenDispaly;   private GesturePoint currentPoint;  private GestureCallBack callBack;  private StringBuilder passWordSb;  private boolean isVerify;  private String passWord;   public GestureDrawline(Context context, List<GesturePoint> list,   boolean isVerify, String passWord, GestureCallBack callBack) {  super(context);  //屏幕参数  screenDispaly = AppUtil.getScreenDispaly(context);  //画笔  paint = new Paint(Paint.DITHER_FLAG);//  //初始化画布--宽高  bitmap = Bitmap.createBitmap(screenDispaly[0], screenDispaly[0],Bitmap.Config.ARGB_8888); //  canvas = new Canvas();  canvas.setBitmap(bitmap);  //设置画笔参数  paint.setStyle(Style.STROKE);  paint.setStrokeWidth(15);//  paint.setColor(getResources().getColor(R.color.gestureline_green));// 设置默认连线颜色  paint.setAntiAlias(true);  //9个点的集合  this.list = list;  //画过的线集合  this.lineList = new ArrayList<Pair<GesturePoint, GesturePoint>>();  initAutoCheckPointMap();  this.callBack = callBack;    this.isVerify = isVerify;  this.passWord = passWord;  //密码集  this.passWordSb = new StringBuilder();  }   private void initAutoCheckPointMap() {  autoCheckPointMap = new HashMap<String, GesturePoint>();  autoCheckPointMap.put("1,3", getGesturePointByNum(2));  autoCheckPointMap.put("1,7", getGesturePointByNum(4));  autoCheckPointMap.put("1,9", getGesturePointByNum(5));  autoCheckPointMap.put("2,8", getGesturePointByNum(5));  autoCheckPointMap.put("3,7", getGesturePointByNum(5));  autoCheckPointMap.put("3,9", getGesturePointByNum(6));  autoCheckPointMap.put("4,6", getGesturePointByNum(5));  autoCheckPointMap.put("7,9", getGesturePointByNum(8));  }   /**得到对应的点位*/  private GesturePoint getGesturePointByNum(int num) {  for (GesturePoint point : list) {   if (point.getNum() == num) {   return point;   }  }  return null;  }   /**将位图绘制到画布上*/  @Override  protected void onDraw(Canvas canvas) {  canvas.drawBitmap(bitmap, 0, 0, null);  }   // 触摸事件  @SuppressLint("ClickableViewAccessibility")  @Override  public boolean onTouchEvent(MotionEvent event) {  if (isDrawEnable == false) {   return true;  }  // 设置默认连线颜色  paint.setColor(getResources().getColor(R.color.gestureline_green));  switch (event.getAction()) {  case MotionEvent.ACTION_DOWN:   mov_x = (int) event.getX();   mov_y = (int) event.getY();   /**获取按下的点位*/   currentPoint = getPointAt(mov_x, mov_y);   if (currentPoint != null) {   /**设置按下的点位的状态,保存密码*/   currentPoint.setPointState(Constants.POINT_STATE_SELECTED, 0, 0);   passWordSb.append(currentPoint.getNum());   }   invalidate();   //回调方法   callBack.onPointDown() ;   break;  case MotionEvent.ACTION_MOVE:   //清楚痕迹   clearScreenAndDrawList();   //移动回调   callBack.onGestureLineMove();   //获取移动到的位置的点位   GesturePoint pointAt = getPointAt((int) event.getX(),    (int) event.getY());   if (currentPoint == null && pointAt == null) {   return true;   } else {   //由间隔处滑到原点处   if (currentPoint == null && pointAt != null) {    // 如果为空,那么把手指移动到的点赋值给currentPoint    currentPoint = pointAt;    /**设置按下的点位的状态,保存密码*/    currentPoint.setPointState(Constants.POINT_STATE_SELECTED,     0, 0);    passWordSb.append(currentPoint.getNum());   }   }   /***/   if (pointAt == null    || currentPoint.equals(pointAt)    || Constants.POINT_STATE_SELECTED == pointAt     .getPointState()) {     canvas.drawLine(currentPoint.getCenterX(),    currentPoint.getCenterY(), event.getX(), event.getY(),    paint);   } else {     int x = pointAt.getCenterX() - currentPoint.getCenterX();   int y = pointAt.getCenterY() - currentPoint.getCenterY();   currentPoint    .setPointState(Constants.POINT_STATE_SELECTED, x, y);   if (pointAt.equals(list.get(list.size() - 1))) {    pointAt    .setPointState(Constants.POINT_STATE_SELECTED, 0, 0);   }    GesturePoint betweenPoint = getBetweenCheckPoint(currentPoint,    pointAt);   if (betweenPoint != null    && Constants.POINT_STATE_SELECTED != betweenPoint     .getPointState()) {     // 存在中间点并且没有被选中    Pair<GesturePoint, GesturePoint> pair1 = new Pair<GesturePoint, GesturePoint>(     currentPoint, betweenPoint);    lineList.add(pair1);    passWordSb.append(betweenPoint.getNum());    Pair<GesturePoint, GesturePoint> pair2 = new Pair<GesturePoint, GesturePoint>(     betweenPoint, pointAt);    lineList.add(pair2);    passWordSb.append(pointAt.getNum());    betweenPoint.setPointState(Constants.POINT_STATE_SELECTED,0, 0);    currentPoint = pointAt;   } else {    Pair<GesturePoint, GesturePoint> pair = new Pair<GesturePoint, GesturePoint>(     currentPoint, pointAt);    lineList.add(pair);    passWordSb.append(pointAt.getNum());    currentPoint = pointAt;   }   }   invalidate();   break;  case MotionEvent.ACTION_UP:   isDrawEnable = false;   if (isVerify) {   // 手势密码校验   String encodeString=MD5EncodeUtil.MD5Ecode(String.valueOf( passWordSb));   String passwordMd5Ecode = MD5EncodeUtil.MD5Ecode(passWord);   if (passwordMd5Ecode.equals(encodeString)) {       callBack.checkedSuccess();   } else {    Log.e("TAG", "encode String fali");    callBack.checkedFail();   }   } else {   //重新绘制界面   clearScreenAndDrawList();   GesturePoint pointAtUp = getPointAt((int) event.getX(),    (int) event.getY());   if (pointAtUp != null    && currentPoint.equals(pointAtUp)    && Constants.POINT_STATE_SELECTED == pointAtUp     .getPointState()&&passWordSb.length()==1) {    currentPoint.setPointState(Constants.POINT_STATE_WRONG,     0, 0);   }   invalidate();   callBack.onGestureCodeInput(passWordSb.toString());   }   break;    default:   break;  }  return true;  }   /**  *  * @param delayTime  *  延迟执行时间  */  public void clearDrawlineState(long delayTime) {  if (delayTime > 0) {   // 绘制红色提示路线   isDrawEnable = false;   drawErrorPathTip();  }  new Handler().postDelayed(new clearStateRunnable(), delayTime);  }   /**  */  final class clearStateRunnable implements Runnable {  public void run() {   // 重置passWordSb   passWordSb = new StringBuilder();   // 清空保存点的集合   lineList.clear();   // 重新绘制界面   clearScreenAndDrawList();   for (GesturePoint p : list) {   p.setPointState(Constants.POINT_STATE_NORMAL, 0, 0);   }   invalidate();   isDrawEnable = true;  }  }   /**  *  * @param x  * @param y  */  private GesturePoint getPointAt(int x, int y) {   for (GesturePoint point : list) {   // 先判断x   int leftX = point.getLeftX();   int rightX = point.getRightX();   if (!(x >= leftX && x < rightX)) {   continue;   }    int topY = point.getTopY();   int bottomY = point.getBottomY();   if (!(y >= topY && y < bottomY)) {   continue;   }    // 如果执行到这,那么说明当前点击的点的位置在遍历到点的位置这个地方   return point;  }   return null;  }   private GesturePoint getBetweenCheckPoint(GesturePoint pointStart,   GesturePoint pointEnd) {  int startNum = pointStart.getNum();  int endNum = pointEnd.getNum();  String key = null;  if (startNum < endNum) {   key = startNum + "," + endNum;  } else {   key = endNum + "," + startNum;  }  return autoCheckPointMap.get(key);  }   /**  * 清掉屏幕上所有的线,然后画出集合里面的线  */  private void clearScreenAndDrawList() {     canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);  for (int i = 0; i < lineList.size(); i++)  {   int r = 0,x,y;   if ((lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2 < 0)   r = -(lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2;   else {   r = (lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2;   }   float d = (float) 0.707 * r;   x = lineList.get(i).second.getCenterX() -lineList.get(i).first.getCenterX();   y = lineList.get(i).second.getCenterY() -lineList.get(i).first.getCenterY();     if (i == lineList.size() - 1) {   lineList.get(i).second.setPointState(Constants.POINT_STATE_SELECTED, 0, 0);   lineList.get(i).first.setPointState(Constants.POINT_STATE_SELECTED, x, y);   }   else {    lineList.get(i).first.setPointState(Constants.POINT_STATE_SELECTED, x, y);    lineList.get(i).second.setPointState(Constants.POINT_STATE_SELECTED, x, y);   }       if (y == 0 && x > 0) {   canvas.drawLine(lineList.get(i).first.getCenterX() + r,    lineList.get(i).first.getCenterY(), lineList.get(i).second.getCenterX() - r,    lineList.get(i).second.getCenterY(), paint);// 画线   }   else if (y == 0 && x < 0 ) {   canvas.drawLine(lineList.get(i).first.getCenterX() - r,    lineList.get(i).first.getCenterY(), lineList.get(i).second.getCenterX() + r,    lineList.get(i).second.getCenterY(), paint);// 画线   }else if (x == 0 && y > 0){   canvas.drawLine(lineList.get(i).first.getCenterX(),    lineList.get(i).first.getCenterY() + r, lineList.get(i).second.getCenterX(),    lineList.get(i).second.getCenterY() - r, paint);// 画线      }else if (x == 0 && y < 0 ) {     canvas.drawLine(lineList.get(i).first.getCenterX(),    lineList.get(i).first.getCenterY() - r, lineList.get(i).second.getCenterX() ,    lineList.get(i).second.getCenterY() + r, paint);// 画线   }   else if( x > 0 && y > 0 ){      canvas.drawLine(lineList.get(i).first.getCenterX() + d,    lineList.get(i).first.getCenterY() + d, lineList.get(i).second.getCenterX() - d ,    lineList.get(i).second.getCenterY() - d, paint);// 画线   }else if(x > 0 && y < 0 )   {      canvas.drawLine(lineList.get(i).first.getCenterX() + d,    lineList.get(i).first.getCenterY() - d, lineList.get(i).second.getCenterX()-d ,    lineList.get(i).second.getCenterY() + d, paint);// 画线     }   else if (x < 0 && y > 0){      canvas.drawLine(lineList.get(i).first.getCenterX() - d,    lineList.get(i).first.getCenterY() + d, lineList.get(i).second.getCenterX()+d ,    lineList.get(i).second.getCenterY() - d, paint);// 画线   }   else if(x < 0 && y < 0 )   {      canvas.drawLine(lineList.get(i).first.getCenterX() - d,    lineList.get(i).first.getCenterY() - d, lineList.get(i).second.getCenterX()+d ,    lineList.get(i).second.getCenterY() + d, paint);// 画线   }  }   }   private void drawErrorPathTip() {     canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);  paint.setColor(getResources().getColor(R.color.gestureline_red));// 设置默认线路颜色  if(lineList.size() == 0 && currentPoint!= null){     currentPoint.setPointState(Constants.POINT_STATE_WRONG, 0, 0);  }  for (int i = 0; i < lineList.size(); i++) {    int r = 0,x,y;   if ((lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2 < 0)   r = -(lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2;   else {   r = (lineList.get(i).first.getTopY() - lineList.get(i).first.getBottomY()) / 2;   }     float d = (float) 0.707 * r;   x = lineList.get(i).second.getCenterX() -lineList.get(i).first.getCenterX();   y = lineList.get(i).second.getCenterY() -lineList.get(i).first.getCenterY();       if (i == lineList.size() - 1) {   lineList.get(i).second.setPointState(Constants.POINT_STATE_WRONG, 0, 0);   lineList.get(i).first.setPointState(Constants.POINT_STATE_WRONG, x, y);   }   else {    lineList.get(i).first.setPointState(Constants.POINT_STATE_WRONG, x, y);    lineList.get(i).second.setPointState(Constants.POINT_STATE_WRONG, x, y);   }     if (y == 0 && x > 0) {      canvas.drawLine(lineList.get(i).first.getCenterX() + r,    lineList.get(i).first.getCenterY(), lineList.get(i).second.getCenterX() - r,    lineList.get(i).second.getCenterY(), paint);// 画线   }   else if (y == 0 && x < 0 ) {   canvas.drawLine(lineList.get(i).first.getCenterX() - r,    lineList.get(i).first.getCenterY(), lineList.get(i).second.getCenterX() + r,    lineList.get(i).second.getCenterY(), paint);// 画线   }else if (x == 0 && y > 0){   canvas.drawLine(lineList.get(i).first.getCenterX(),    lineList.get(i).first.getCenterY() + r, lineList.get(i).second.getCenterX(),    lineList.get(i).second.getCenterY() - r, paint);// 画线      }else if (x == 0 && y < 0 ) {     canvas.drawLine(lineList.get(i).first.getCenterX(),    lineList.get(i).first.getCenterY() - r, lineList.get(i).second.getCenterX() ,    lineList.get(i).second.getCenterY() + r, paint);// 画线   }   else if( x > 0 && y > 0 ){      canvas.drawLine(lineList.get(i).first.getCenterX() + d,    lineList.get(i).first.getCenterY() + d, lineList.get(i).second.getCenterX() - d ,    lineList.get(i).second.getCenterY() - d, paint);// 画线   }else if(x > 0 && y < 0 )   {      canvas.drawLine(lineList.get(i).first.getCenterX() + d,    lineList.get(i).first.getCenterY() - d, lineList.get(i).second.getCenterX()-d ,    lineList.get(i).second.getCenterY() + d, paint);// 画线     }   else if (x < 0 && y > 0){      canvas.drawLine(lineList.get(i).first.getCenterX() - d,    lineList.get(i).first.getCenterY() + d, lineList.get(i).second.getCenterX()+d ,    lineList.get(i).second.getCenterY() - d, paint);// 画线   }   else if(x < 0 && y < 0 )   {      canvas.drawLine(lineList.get(i).first.getCenterX() - d,    lineList.get(i).first.getCenterY() - d, lineList.get(i).second.getCenterX()+d ,    lineList.get(i).second.getCenterY() + d, paint);// 画线   }  }  invalidate();  }    public interface GestureCallBack {   public abstract void onGestureCodeInput(String inputCode);   public abstract void checkedSuccess();   public abstract void checkedFail();      public abstract void onGestureLineMove();    public abstract void onPointDown() ;  }  } 

ok 注备工作进行完毕,接下来看设置手势密码界面
gesture_edit.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="vertical"  android:background="#f2f2f2" >   <LinearLayout  android:id="@+id/ll_head"  android:layout_width="fill_parent"  android:layout_height="48dp"  android:background="@drawable/bg_head"  android:gravity="center_vertical"  android:orientation="horizontal" >   <LinearLayout   android:id="@+id/ll_head_left"   android:layout_width="wrap_content"   android:layout_height="fill_parent"   android:layout_marginTop="1dp"   android:gravity="center_vertical"   android:background="@drawable/selector_head_back"   android:orientation="horizontal" >    <ImageView   android:id="@+id/im_back"   android:layout_width="7dp"   android:layout_height="14dp"   android:layout_marginLeft="5dp"   android:background="@drawable/back" />    <TextView   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_marginLeft="5dp"   android:text="@string/set_gesture_code"   android:textColor="#fff"   android:textSize="17.33dp" />  </LinearLayout>   <View   android:layout_width="0dp"   android:layout_height="fill_parent"   android:layout_weight="1" />  </LinearLayout>   <LinearLayout  android:id="@+id/gesture_tip_layout"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:layout_marginTop="75.67dp"  android:orientation="vertical" >   <TextView   android:id="@+id/tv_edit_texttip"   android:layout_width="fill_parent"   android:layout_height="wrap_content"   android:gravity="center_horizontal"   android:text="@string/set_gesture_pattern"   android:textColor="@color/color_black"   android:textSize="@dimen/textsize_s3" />  </LinearLayout>   <RelativeLayout  android:id="@+id/fl_edit_gesture_container"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_marginTop="48dp"  android:gravity="center_horizontal" >  </RelativeLayout>   </LinearLayout> 

GestureEditActivity

package com.example.gesturelock;  import android.app.Activity; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.os.Handler; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView;  import com.example.gesturelock.GestureDrawline.GestureCallBack;   public class GestureEditActivity extends Activity implements OnClickListener {   private LinearLayout im_back;  private TextView tv_texttip;  private RelativeLayout mGestureContainer;  private GestureContentView mGestureContentView;  // 第一次输入的密码  private String mFirstPassword = null;  // 是不是第一次输入  private boolean mIsFirstInput = true;  static final String TABLES_NAME_GESTURE = "gesture_password";   public final static int GESTURE_TIME = 8;   private publicSQLiteOpenHelper sqliteInstance;  private SQLiteDatabase database;  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.gesture_edit);  // 错误提示  tv_texttip = (TextView) findViewById(R.id.tv_edit_texttip);  // 9点区域  mGestureContainer = (RelativeLayout) findViewById(R.id.fl_edit_gesture_container);  // 返回  im_back = (LinearLayout) findViewById(R.id.ll_head_left);  // 初始化继续不可点击  im_back.setOnClickListener(this);   mGestureContentView = new GestureContentView(this, false, "",   new GestureCallBack() {         @Override    public void onGestureCodeInput(String inputCode) {       if (mIsFirstInput) { // 第一次输入手势密码     if (!isInputPassValidate(inputCode)) {     // 至少连接4个点     tv_texttip.setText(getResources().getString(      R.string.drawguesturewarning));     // 2秒后清除界面     mGestureContentView.clearDrawlineState(2000L);     // 2秒后还原提示     mHandler.postDelayed(connect4Dot, 2000);     return;     }else {     mFirstPassword = inputCode;          tv_texttip.setText(getResources().getString(      R.string.drawguestureagain));     mHandler.postDelayed(clearGreenLine, 1000);     mIsFirstInput = false;     }    } else {     if (inputCode.equals(mFirstPassword)) { // 第二次输入手势密码与第一次一致     tv_texttip.setText(getResources().getString(      R.string.your_gesture_code));      sqliteInstance = new publicSQLiteOpenHelper(GestureEditActivity.this);     database = sqliteInstance.getWritableDatabase();     boolean count = sqliteInstance.queryGestureTableCount(database);     if (count) {      //如果有记录      sqliteInstance.updateGestureInfo(database,mFirstPassword, "8");     }else {      //如果没有记录      sqliteInstance.insertGestureInfo(database,mFirstPassword, "8");      }      mHandler.postDelayed(setGestureOkFinish, 1000);     } else {      if (!isInputPassValidate(inputCode)) {      // 至少连接4个点      tv_texttip.setText(getResources().getString(       R.string.drawguesturewarning));      // 2秒后清除界面      mGestureContentView.clearDrawlineState(2000L);      // 2秒后还原提示      mHandler.postDelayed(connect4Dot, 2000);     } else { // 第二次输入手势密码与第一次不一致      tv_texttip.setText(getResources()       .getString(R.string.drawagain));      // 左右移动动画 //     Animation shakeAnimation = //     AnimationUtils.loadAnimation(GestureEditActivity.this,R.anim.shake); //     tv_texttip.startAnimation(shakeAnimation);      // 保持绘制的线,1.5秒后清除      mGestureContentView       .clearDrawlineState(2000L);      mHandler.postDelayed(changeText2again, 2000);     }      }    }       }     @Override    public void checkedFail() {     }     @Override    public void onGestureLineMove() {    tv_texttip.setText(getResources().getString(     R.string.release_hande_when_finish));    }     @Override    public void onPointDown() {     }     @Override    public void checkedSuccess() {     }   });  // 设置手势解锁显示到哪个布局里面  mGestureContentView.setParentView(mGestureContainer);  }   @Override  protected void onResume() {  super.onResume();  }   Handler mHandler = new Handler();   Runnable clearGreenLine = new Runnable() {  public void run() {   mGestureContentView.clearDrawlineState(0L);  }  };   Runnable connect4Dot = new Runnable() {  public void run() {   tv_texttip.setText(getResources().getString(    R.string.set_gesture_pattern));  }  };   Runnable setGestureOkFinish = new Runnable() {  public void run() {   finish();  }  };  Runnable changeText2again = new Runnable() {  public void run() {   tv_texttip.setText(getResources().getString(    R.string.drawguestureagain));  }  };   private boolean isInputPassValidate(String inputPassword) {  if (TextUtils.isEmpty(inputPassword) || inputPassword.length() < 4) {   return false;  }  return true;  }    protected void onDestroy() {  super.onDestroy();  }   @Override  public void onClick(View v) {  switch (v.getId()) {  case R.id.ll_head_left:   finish();   break;  }  } } 

最后看校验界面
gesture_verify.xml

<?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:orientation="vertical"  android:layout_height="match_parent"  android:background="@color/color_main" >   <LinearLayout  android:id="@+id/ll_head"  android:layout_width="fill_parent"  android:layout_height="48dp"  android:background="@drawable/bg_head"  android:gravity="center_vertical"  android:orientation="horizontal" >   <LinearLayout   android:id="@+id/ll_head_left"   android:layout_width="wrap_content"   android:layout_height="fill_parent"   android:layout_marginTop="1dp"   android:gravity="center_vertical"   android:background="@drawable/selector_head_back"   android:orientation="horizontal" >    <ImageView   android:id="@+id/im_back"   android:layout_width="7dp"   android:layout_height="14dp"   android:layout_marginLeft="5dp"   android:background="@drawable/back" />    <TextView   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_marginLeft="5dp"   android:text="@string/verify_gesture_code"   android:textColor="#fff"   android:textSize="17.33dp" />  </LinearLayout>   <View   android:layout_width="0dp"   android:layout_height="fill_parent"   android:layout_weight="1" />  </LinearLayout>    <LinearLayout  android:id="@+id/gesture_tip_layout"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:layout_marginTop="75.67dp"  android:orientation="vertical" >   <TextView   android:id="@+id/tv_edit_texttip"   android:layout_width="fill_parent"   android:layout_height="wrap_content"   android:gravity="center_horizontal"   android:text="@string/set_gesture_pattern"   android:textColor="@color/color_black"   android:textSize="@dimen/textsize_s3" />  </LinearLayout>  <RelativeLayout  android:id="@+id/fl_verify_gesture_container"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_marginTop="48dp"  android:gravity="center_horizontal" >  </RelativeLayout>    </LinearLayout> 

最后校验代码

package com.example.gesturelock;  import java.util.Timer; import java.util.TimerTask;  import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView;  import com.example.gesturelock.GestureDrawline.GestureCallBack;   public class GestureVerifyActivity extends Activity {  private static String TAG = "GestureVerifyActivity";  private TextView tv_texttip;  private RelativeLayout mGestureContainer;  private LinearLayout ib_back;  private GestureContentView mGestureContentView;  private Timer timer = new Timer() ;  private TimerTask closeActivityTask = null;   static final String TABLES_NAME_GESTURE = "gesture_password";  private int remainopportunity ;   private publicSQLiteOpenHelper sqliteInstance;  private SQLiteDatabase database;   private void resetCloseEvent(){  clearCloseEvent() ;  closeActivityTask = new TimerTask() {   public void run() {   Message message = new Message();   message.what = 1;   handler.sendMessage(message);   }  };  timer.schedule(closeActivityTask, 30000);  }  private void clearCloseEvent(){  if(closeActivityTask != null){   closeActivityTask.cancel() ;   closeActivityTask = null ;   Log.i(TAG, "----------closeActivityTask----------"+closeActivityTask);  }  }    public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.gesture_verify);   resetCloseEvent();   tv_texttip = (TextView) findViewById(R.id.tv_edit_texttip);  ib_back = (LinearLayout) findViewById(R.id.ll_head_left);  mGestureContainer = (RelativeLayout) findViewById(R.id.fl_verify_gesture_container);    sqliteInstance = new publicSQLiteOpenHelper(GestureVerifyActivity.this);  database = sqliteInstance.getWritableDatabase();  //从数据库中获取手势密码、剩余次数  firstPassward = sqliteInstance.queryGesturePassword(database);  remainopportunityStr = sqliteInstance.queryGestureTime(database);  if (TextUtils.isEmpty(remainopportunityStr)) {   remainopportunity = 8;   //初始化8次   sqliteInstance.updateGestureInfo(database,null, "8");  } else {   remainopportunity = Integer.parseInt(remainopportunityStr);  }  if(remainopportunity == 0){   tv_texttip.setTextColor(getResources().getColor(R.color.gestureline_red));   tv_texttip.setText(getResources().getString(R.string.no_chance));  }    ib_back.setOnClickListener(new View.OnClickListener() {     @Override   public void onClick(View v) {   finish();   }  });     mGestureContentView = new GestureContentView(this, true, firstPassward,   new GestureCallBack() {    @Override    public void onGestureCodeInput(String inputCode) {         }     @SuppressLint("ShowToast")    @Override    public void checkedSuccess() {        sqliteInstance.updateGestureInfo(database,null, "8");    mGestureContentView.clearDrawlineState(0L);    resetCloseEvent();    finish();    //发送广播    sendBroadcast(new Intent("com.godinsec.seland.intent.CASIntent.INTENT_LOAD_SD"));        }    @Override    public void checkedFail() {    mGestureContentView.clearDrawlineState(2000L);    tv_texttip.setTextColor(getResources().getColor(R.color.gestureline_red));    if(remainopportunity > 0){     remainopportunity-- ;    }    sqliteInstance.updateGestureInfo(database,null, ""+remainopportunity);    resetCloseEvent();    changeText();        }     @Override    public void onGestureLineMove() {    if(remainopportunity > 0){     tv_texttip.setTextColor(getResources().getColor(R.color.textcolor_black_bb));     tv_texttip.setText(getResources().getString(R.string.release_hande_when_finish));    }    }     @Override    public void onPointDown() {    clearCloseEvent() ;    }      });  mGestureContentView.setParentView(mGestureContainer);  }   protected void changeText() {  Log.e("TAGG", "changeText");  if (remainopportunity == 7) {   tv_texttip.setText(getResources().getString(    R.string.wrong_answer_seven));  } else if (remainopportunity == 6) {   tv_texttip.setText(getResources().getString(    R.string.wrong_answer_six));  } else if (remainopportunity == 5) {   tv_texttip.setText(getResources().getString(    R.string.wrong_answer_five));  } else if (remainopportunity == 4) {   tv_texttip.setText(getResources().getString(    R.string.wrong_answer_four));  } else if (remainopportunity == 3) {   tv_texttip.setText(getResources().getString(    R.string.wrong_answer_three));  } else if (remainopportunity == 2) {   tv_texttip.setText(getResources().getString(    R.string.wrong_answer_two));  } else if (remainopportunity == 1) {   tv_texttip.setText(getResources().getString(    R.string.wrong_answer_one));  } else {   tv_texttip.setText(getResources().getString(    R.string.wrong_answer_zero));   handler.postDelayed(errorFinish, 2000);  }  }   @Override  protected void onResume() {  super.onResume();  }   Runnable errorFinish = new Runnable() {  public void run() {   finish();  }  };   @SuppressLint("HandlerLeak")  Handler handler = new Handler() {   @Override  public void handleMessage(Message msg) {   super.handleMessage(msg);   switch (msg.what) {   case 1:   finish();   break;   }  }  };  private String remainopportunityStr;  private String firstPassward;   protected void onDestroy() {  super.onDestroy();  }  protected void onStop() {  super.onStop();  } } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表