Android自定义UI手势密码简单版
程序员文章站
2024-03-02 18:01:52
先看看效果图:
imagelockactivity
package com.example.imagelock;
import com.exa...
先看看效果图:
imagelockactivity
package com.example.imagelock; import com.example.view.ninepointlineview; import android.os.bundle; import android.app.activity; import android.view.menu; import android.view.view; public class imagelockactivity extends activity { @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); view v = new ninepointlineview(this); setcontentview(v); } }
ninepointlineview
package com.example.view; import com.example.imagelock.r; 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.cap; import android.graphics.typeface; import android.util.attributeset; import android.view.motionevent; import android.view.view; import android.widget.toast; public class ninepointlineview extends view { /** * 定义3个paint,还有一个坐标圆点图片 */ paint linepaint = new paint(); paint whitelinepaint = new paint(); paint textpaint = new paint(); bitmap defaultbitmap = bitmapfactory.decoderesource(getresources(),r.drawable.lock); pointinfo[] points = new pointinfo[9]; int width, height; //坐标点的半径长度 int defaultbitmapradius = defaultbitmap.getwidth() / 2; //绘制密码时候出现的原点的直径,半径 bitmap selectedbitmap = bitmapfactory.decoderesource(getresources(), r.drawable.indicator_lock_area); int selectedbitmapdiameter = selectedbitmap.getwidth(); int selectedbitmapradius = selectedbitmapdiameter / 2; stringbuffer lockstring = new stringbuffer(); context context; /** 构造器*********************************************/ public ninepointlineview(context context) { super(context); this.context = context; this.setbackgroundcolor(color.white); initpaint(); } public ninepointlineview(context context, attributeset attrs) { super(context, attrs); this.context = context; this.setbackgroundcolor(color.white); initpaint(); } private void initpaint() { //线--包裹9个原点 linepaint.setcolor(color.red); linepaint.setstrokewidth(defaultbitmap.getwidth()); linepaint.setantialias(true); linepaint.setstrokecap(cap.round); //线内--比原点直径少5 whitelinepaint.setcolor(color.green); whitelinepaint.setstrokewidth(defaultbitmap.getwidth() - 5); whitelinepaint.setantialias(true); whitelinepaint.setstrokecap(cap.round); //字体设置 textpaint.settextsize(30); textpaint.setantialias(true); textpaint.settypeface(typeface.monospace); } /********************************************************** * 测量 */ @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { width = getwidth(); height = getheight(); if (width != 0 && height != 0) { initpoints(points); } super.onmeasure(widthmeasurespec, heightmeasurespec); } /** * 初始化原点 */ private void initpoints(pointinfo[] points) { int len = points.length; //2个原点的间距 int seletedspacing = (width - selectedbitmapdiameter * 3) / 4; //第1个原点的坐标 int seletedx = seletedspacing; int seletedy = height - width + seletedspacing; //第1个原点内部的小圆的坐标 int defaultx = seletedx + selectedbitmapradius - defaultbitmapradius; int defaulty = seletedy + selectedbitmapradius - defaultbitmapradius; for (int i = 0; i < len; i++) { //第4、7个原点 if (i == 3 || i == 6) { seletedx = seletedspacing; //第一个原点y坐标+直径+2点间距离 seletedy += selectedbitmapdiameter + seletedspacing; defaultx = seletedx + selectedbitmapradius - defaultbitmapradius; //第一个原点y坐标+直径+2点间距离 defaulty += selectedbitmapdiameter + seletedspacing; } points[i] = new pointinfo(i, defaultx, defaulty, seletedx, seletedy); //原点坐标xy为直径+2点间距离 seletedx += selectedbitmapdiameter + seletedspacing; defaultx += selectedbitmapdiameter + seletedspacing; } } /*****************************************************************/ @override protected void onlayout(boolean changed, int left, int top, int right, int bottom) { super.onlayout(changed, left, top, right, bottom); } private int startx = 0, starty = 0; pointinfo startpoint = null; @override protected void ondraw(canvas canvas) { drawninepoint(canvas); super.ondraw(canvas); } /** * * @param canvas */ private void drawninepoint(canvas canvas) { if (startpoint != null) { draweachline(canvas, startpoint); } for(pointinfo pointinfo : points) { if (pointinfo!=null) { if (pointinfo.isselected()) { canvas.drawbitmap(selectedbitmap, pointinfo.getseletedx(),pointinfo.getseletedy(), null); } canvas.drawbitmap(defaultbitmap, pointinfo.getdefaultx(),pointinfo.getdefaulty(), null); } } } private void draweachline(canvas canvas, pointinfo point) { if (point.hasnextid()) { int n = point.getnextid(); drawline(canvas, point.getcenterx(), point.getcentery(), points[n].getcenterx(), points[n].getcentery()); draweachline(canvas, points[n]); } } private void drawline(canvas canvas, float startx, float starty, float stopx, float stopy) { canvas.drawline(startx, starty, stopx, stopy, linepaint); canvas.drawline(startx, starty, stopx, stopy, whitelinepaint); } /** * ******************************************************************** */ boolean isup = false; int movex, movey; @override public boolean ontouchevent(motionevent event) { boolean flag = true; //isup默认是false--绘制是否完毕,此时为true if (isup) { finishdraw(); toast.maketext(context, "绘制完毕,手指离开,在点击", 0).show(); flag = false; } else { handlingevent(event); flag = true; toast.maketext(context, "手指一旦绘制", 0).show(); } //是否处理事件 return flag; } private void finishdraw() { for (pointinfo temp : points) { temp.setselected(false); temp.setnextid(temp.getid()); } lockstring.delete(0, lockstring.length()); isup = false; invalidate(); } private void handlingevent(motionevent event) { switch (event.getaction()) { case motionevent.action_move: movex = (int) event.getx(); movey = (int) event.gety(); for (pointinfo temp : points) { if (temp.isinmyplace(movex, movey) && temp.isselected()==false) { temp.setselected(true); startx = temp.getcenterx(); starty = temp.getcentery(); int len = lockstring.length(); if (len != 0) { int preid = lockstring.charat(len - 1) - 48; points[preid].setnextid(temp.getid()); } lockstring.append(temp.getid()); break; } } invalidate(); break; case motionevent.action_down: //获取按下的xy坐标 int downx = (int) event.getx(); int downy = (int) event.gety(); for (pointinfo temp : points) { //如果符合距离范围内 if (temp.isinmyplace(downx, downy)) { //将其设置为选中状态 temp.setselected(true); //将选中的圆点设置为起始位置圆点 startpoint = temp; //将其圆心作为起始点 startx = temp.getcenterx(); starty = temp.getcentery(); lockstring.append(temp.getid()); break; } } invalidate(); break; case motionevent.action_up: startx = starty = movex = movey = 0; //绘制完毕 isup = true; invalidate(); break; default: break; } } /** * 原点bean */ private class pointinfo { private boolean selected; private int id; private int nextid; private int defaultx; private int defaulty; private int seletedx; private int seletedy; public pointinfo(int id, int defaultx, int defaulty, int seletedx, int seletedy) { this.id = id; this.nextid = id; this.defaultx = defaultx; this.defaulty = defaulty; this.seletedx = seletedx; this.seletedy = seletedy; } public boolean isselected() { return selected; } public void setselected(boolean selected) { this.selected = selected; } public int getid() { return id; } public int getdefaultx() { return defaultx; } public int getdefaulty() { return defaulty; } public int getseletedx() { return seletedx; } public int getseletedy() { return seletedy; } public int getcenterx() { return seletedx + selectedbitmapradius; } public int getcentery() { return seletedy + selectedbitmapradius; } public boolean hasnextid() { return nextid != id; } public int getnextid() { return nextid; } public void setnextid(int nextid) { this.nextid = nextid; } /** * 如果某个xy值在某个原点的左右上下范围内,就说明ok */ public boolean isinmyplace(int x, int y) { boolean inx = x > seletedx && x < (seletedx + selectedbitmapdiameter); boolean iny = y > seletedy && y < (seletedy + selectedbitmapdiameter); return (inx && iny); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 浅谈Java程序运行机制及错误分析