欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义UI手势密码改进版

程序员文章站 2024-03-03 23:53:40
接着android ui手势密码设计的基础上继续改进,效果图如下 activity_main.xml

接着android ui手势密码设计的基础上继续改进,效果图如下

Android自定义UI手势密码改进版

activity_main.xml

<linearlayout 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:orientation="vertical" 
 tools:context=".mainactivity" > 
 
 <textview 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:gravity="center" 
 android:text="请输入密码" 
 android:id="@+id/text" 
 /> 
 
 <com.example.lockpatterview.lockpatterview 
 android:id="@+id/lock" 
 android:layout_weight="1" 
 android:layout_width="match_parent" 
 android:layout_height="0dp" /> 
 
</linearlayout> 

mainactivity

package com.example.lockpatterview; 
 
import com.example.lockpatterview.lockpatterview.onpatterchangelister; 
 
import android.os.bundle; 
import android.text.textutils; 
import android.widget.textview; 
import android.widget.toast; 
import android.app.activity; 
 
public class mainactivity extends activity implements onpatterchangelister { 
 
 lockpatterview lock; 
 textview text; 
 string p = "14789"; 
 
 @override 
 protected void oncreate(bundle savedinstancestate) { 
 super.oncreate(savedinstancestate); 
 setcontentview(r.layout.activity_main); 
 text = (textview) findviewbyid(r.id.text); 
 lock = (lockpatterview) findviewbyid(r.id.lock); 
 lock.setonpatterchangelister(this); 
 } 
 
 @override 
 public void onpatterchange(string passwordstr) { 
 if (!textutils.isempty(passwordstr)) { 
  if (passwordstr.equals(p)) { 
  text.settext(passwordstr); 
  } else { 
  text.settext("密码错误"); 
  lock.errorpoint(); 
  } 
 }else { 
  toast.maketext(mainactivity.this, "至少连接5点", 0).show(); 
 } 
 
 } 
 
 @override 
 public void onpatterstart(boolean isstart) { 
 if (isstart) { 
  text.settext("请绘制图案"); 
 } 
 } 
 
} 

lockpatterview

package com.example.lockpatterview; 
 
import java.util.arraylist; 
import java.util.list; 
 
import android.content.context; 
import android.graphics.bitmap; 
import android.graphics.bitmapfactory; 
import android.graphics.canvas; 
import android.graphics.matrix; 
import android.graphics.paint; 
import android.text.textutils; 
import android.util.attributeset; 
import android.view.motionevent; 
import android.view.view; 
 
public class lockpatterview extends view { 
 
 private static final int point_size = 5; 
 
 private point[][] points = new point[3][3]; 
 
 private matrix matrix = new matrix(); 
 
 private float width, height, offstarty, movex, movey;; 
 
 private bitmap bitmap_pressed, bitmap_normal, bitmap_error, bitmap_line, 
  bitmap_line_error; 
 
 private paint paint = new paint(paint.anti_alias_flag); 
 
 private list<point> pointlist = new arraylist<lockpatterview.point>(); 
 
 private onpatterchangelister onpatterchangelister; 
 
 /** 
 * 构造函数 
 */ 
 public lockpatterview(context context, attributeset attrs, int defstyle) { 
 super(context, attrs, defstyle); 
 } 
 
 public lockpatterview(context context, attributeset attrs) { 
 super(context, attrs); 
 } 
 
 public lockpatterview(context context) { 
 super(context); 
 } 
 
 /********************************************************* 
 * 绘制9宫格 
 * movepoint代表鼠标在移动,但是不是9宫格里面的点 
 * isinit是否初始化过9个点 
 * isselect 点位是否被选中状态 
 * isfinish 是否绘制完毕 
 */ 
 private boolean isinit, isselect, isfinish, movepoint; 
 
 @override 
 protected void ondraw(canvas canvas) { 
 // 第一次没有初始化就进行初始化,一旦初始化就不在初始化工作了,isinit的意思是---默认没有初始化过 
 if (!isinit) { 
  // 初始化9个点 
  initpoints(); 
 } 
 // 绘制9个点 
 points2canvas(canvas); 
 
 if (pointlist.size() > 0) { 
  point a = pointlist.get(0); 
  // 绘制九宫格坐标点 
  for (int i = 0; i < pointlist.size(); i++) { 
  point b = pointlist.get(i); 
  line2canvas(canvas, a, b); 
  a = b; 
  } 
  // 绘制鼠标坐标点 
  if (movepoint) { 
  line2canvas(canvas, a, new point(movex, movey)); 
  } 
 } 
 } 
 
 /** 
 * 初始化9个点位 获取点位的3种状态 线的2种状态 以及9点的坐标位置 以及初始化密码操作 isinit= 
 * true设置状态--下次不必初始化话工作了 
 */ 
 private void initpoints() { 
 
 // 获取布局宽高 
 width = getwidth(); 
 height = getheight(); 
 
 // 横屏和竖屏 
 
 offstarty = (height - width) / 2; 
 
 // 图片资源 
 bitmap_normal = bitmapfactory.decoderesource(getresources(), 
  r.drawable.btn_circle_normal); 
 bitmap_pressed = bitmapfactory.decoderesource(getresources(), 
  r.drawable.btn_circle_pressed); 
 bitmap_error = bitmapfactory.decoderesource(getresources(), 
  r.drawable.btn_circle_selected); 
 bitmap_line = bitmapfactory.decoderesource(getresources(), 
  r.drawable.ddd); 
 bitmap_line_error = bitmapfactory.decoderesource(getresources(), 
  r.drawable.qqq); 
 
 points[0][0] = new point(width / 4, offstarty + width / 4); 
 points[0][1] = new point(width / 2, offstarty + width / 4); 
 points[0][2] = new point(width / 4 * 3, offstarty + width / 4); 
 
 points[1][0] = new point(width / 4, offstarty + width / 4 * 2); 
 points[1][1] = new point(width / 2, offstarty + width / 4 * 2); 
 points[1][2] = new point(width / 4 * 3, offstarty + width / 4 * 2); 
 
 points[2][0] = new point(width / 4, offstarty + width / 4 * 3); 
 points[2][1] = new point(width / 2, offstarty + width / 4 * 3); 
 points[2][2] = new point(width / 4 * 3, offstarty + width / 4 * 3); 
 
 // 设置密码1--9 
 int index = 1; 
 for (point[] points : this.points) { 
  for (point point : points) { 
  point.index = index; 
  index++; 
  } 
 } 
 // 初始化完成 
 isinit = true; 
 } 
 
 /** 
 * 将9个点绘制到画布 循环遍历9个点位, 根据3种不同的状态绘制3种不同的9个点位 
 */ 
 private void points2canvas(canvas canvas) { 
 // 循环遍历9个点位 
 for (int i = 0; i < points.length; i++) { 
  // 循环遍历每行的3个点位 
  for (int j = 0; j < points[i].length; j++) { 
  // 获取依次的某个点位 
  point point = points[i][j]; 
  if (point.state == point.state_pressed) { 
   // (bitmap bitmap, float left, float top, paint paint) 
   canvas.drawbitmap(bitmap_pressed, 
    point.x - bitmap_normal.getwidth() / 2, point.y 
     - bitmap_normal.getheight() / 2, paint); 
  } else if (point.state == point.state_error) { 
   canvas.drawbitmap(bitmap_error, 
    point.x - bitmap_normal.getwidth() / 2, point.y 
     - bitmap_normal.getheight() / 2, paint); 
  } else { 
   canvas.drawbitmap(bitmap_normal, 
    point.x - bitmap_normal.getwidth() / 2, point.y 
     - bitmap_normal.getheight() / 2, paint); 
  } 
  } 
 } 
 } 
 
 /** 
 * 画线 
 */ 
 public void line2canvas(canvas canvas, point a, point b) { 
 // 线的长度--2点之间的距离 
 float linelength = (float) point.distance(a, b); 
 // 获取2点之间的角度 
 float degress = getdegrees(a, b); 
 //根据a点进行旋转 
 canvas.rotate(degress, a.x, a.y); 
 
 if (a.state == point.state_pressed) { 
  // xy方向上的缩放比例 
  matrix.setscale(linelength / bitmap_line.getwidth(), 1); 
  matrix.posttranslate(a.x - bitmap_line.getwidth() / 2, a.y 
   - bitmap_line.getheight() / 2); 
  canvas.drawbitmap(bitmap_line, matrix, paint); 
 } else { 
  matrix.setscale(linelength / bitmap_line.getwidth(), 1); 
  matrix.posttranslate(a.x - bitmap_line.getwidth() / 2, a.y 
   - bitmap_line.getheight() / 2); 
  canvas.drawbitmap(bitmap_line_error, matrix, paint); 
 } 
 //画线完毕回归角度 
 canvas.rotate(-degress, a.x, a.y); 
 } 
 
 // 获取角度 
 public float getdegrees(point pointa, point pointb) { 
 return (float) math.todegrees(math.atan2(pointb.y - pointa.y, pointb.x 
  - pointa.x)); 
 } 
 
 /**************************************************************************** 
 * ontouch事件处理 
 */ 
 
 @override 
 public boolean ontouchevent(motionevent event) { 
 movex = event.getx(); 
 movey = event.gety(); 
 
 movepoint = false; 
 isfinish = false; 
 
 point point = null; 
 
 switch (event.getaction()) { 
 //只要按下操作,就代表重新绘制界面 
 case motionevent.action_down: 
  if (onpatterchangelister != null) { 
  onpatterchangelister.onpatterstart(true); 
  } 
  // 每次按下,都需要清空之前的集合 
  resetpoint(); 
  // 检测是不是在九宫格内 
  point = chechselectpoint(); 
  if (point != null) { 
  //如果按下的位置在9宫格内,就改成状态为true 
  isselect = true; 
  } 
  break; 
 case motionevent.action_move: 
  if (isselect) { 
  // 检测是不是在九宫格内 
  point = chechselectpoint(); 
  if (point == null) { 
   movepoint = true; 
  } 
  } 
  break; 
 case motionevent.action_up: 
  //绘制完毕,点位状态改为未选中 
  isfinish = true; 
  isselect = false; 
  break; 
 
 } 
 // 如果没有绘制完毕,如果九宫格处于选中状态 
 if (!isfinish && isselect && point != null) { 
  // 交叉点 
  if (crosspoint(point)) { 
  movepoint = true; 
  } else {// 新点 
  point.state = point.state_pressed; 
  pointlist.add(point); 
  } 
 } 
 
 // 绘制结束 
 if (isfinish) { 
  // 绘制不成立 
  if (pointlist.size() == 1) { 
  // resetpoint(); 
  errorpoint(); 
  } else if (pointlist.size() < point_size && pointlist.size() > 0) {// 绘制错误 
  errorpoint(); 
  if (onpatterchangelister != null) { 
   onpatterchangelister.onpatterchange(null); 
  } 
  } else { 
  if (onpatterchangelister != null) { 
   string pass = ""; 
   for (int i = 0; i < pointlist.size(); i++) { 
   pass = pass + pointlist.get(i).index; 
   } 
   if (!textutils.isempty(pass)) { 
   onpatterchangelister.onpatterchange(pass); 
   } 
  } 
  } 
 } 
 
 postinvalidate(); 
 return true; 
 } 
 
 /** 
 * 重新绘制 
 */ 
 public void resetpoint() { 
 for (int i = 0; i < pointlist.size(); i++) { 
  point point = pointlist.get(i); 
  point.state = point.state_normal; 
 } 
 pointlist.clear(); 
 } 
 
 /** 
 * 检查是否选中 
 */ 
 private point chechselectpoint() { 
 for (int i = 0; i < points.length; i++) { 
  for (int j = 0; j < points[i].length; j++) { 
  point point = points[i][j]; 
  if (point.with(point.x, point.y, bitmap_normal.getwidth() / 2, 
   movex, movey)) { 
   return point; 
  } 
  } 
 } 
 
 return null; 
 } 
 
 /** 
 * 交叉点 
 */ 
 private boolean crosspoint(point point) { 
 if (pointlist.contains(point)) { 
  return true; 
 } else { 
  return false; 
 } 
 } 
 
 /** 
 * 绘制错误 
 */ 
 public void errorpoint() { 
 for (point point : pointlist) { 
  point.state = point.state_error; 
 } 
 } 
 
 /*********************************************************************** 
 * 自定义的点 
 */ 
 public static class point { 
 // 正常 
 public static int state_normal = 0; 
 // 选中 
 public static int state_pressed = 1; 
 // 错误 
 public static int state_error = 2; 
 public float x, y; 
 public int index = 0, state = 0; 
 
 public point() { 
 }; 
 
 public point(float x, float y) { 
  this.x = x; 
  this.y = y; 
 } 
 
 /** 
  * 两点之间的距离 
  */ 
 public static double distance(point a, point b) { 
  return math.sqrt(math.abs(a.x - b.x) * math.abs(a.x - b.x) 
   + math.abs(a.y - b.y) * math.abs(a.y - b.y)); 
 } 
 
 /** 
  */ 
 public static boolean with(float paintx, float pointy, float r, 
  float movex, float movey) { 
  return math.sqrt((paintx - movex) * (paintx - movex) 
   + (pointy - movey) * (pointy - movey)) < r; 
 } 
 } 
 
 /** 
 * 图案监听器 
 */ 
 public static interface onpatterchangelister { 
 void onpatterchange(string passwordstr); 
 
 void onpatterstart(boolean isstart); 
 } 
 
 /** 
 * 设置图案监听器 
 */ 
 public void setonpatterchangelister(onpatterchangelister changelister) { 
 if (changelister != null) { 
  this.onpatterchangelister = changelister; 
 } 
 } 
} 

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