先看看效果图:
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); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍Android自定义UI手势密码改进版,包括了Android自定义UI手势密码改进版的使用技巧和注意事项,需要的朋友参考一下 接着第一个Android UI手势密码设计的基础上继续改进,效果图如下 activity_main.xml MainActivity LockPatterView 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍Android自定义UI手势密码终结版,包括了Android自定义UI手势密码终结版的使用技巧和注意事项,需要的朋友参考一下 之前写过3篇手势密码的demo,不过没有集成到真实的企业项目中,这几天正好领到一个手势密码项目,昨天刚好弄完,今天抽空整理下,目前还没有完善,有一些地方需要更改,不过基本的流程都可以跑通了。 源码下载地址:http://xiazai.jb51.net/2016
本文向大家介绍Android自定义UI手势密码改进版源码下载,包括了Android自定义UI手势密码改进版源码下载的使用技巧和注意事项,需要的朋友参考一下 在之前文章的铺垫下,再为大家分享一篇:Android手势密码,附源码下载,不要错过。 源码下载:http://xiazai.jb51.net/201610/yuanma/androidLock(jb51.net).rar 先看第一张图片的布局文
本文向大家介绍Android自定义控件实现手势密码,包括了Android自定义控件实现手势密码的使用技巧和注意事项,需要的朋友参考一下 Android手势解锁密码效果图 首先呢想写这个手势密码的想法呢,完全是凭空而来的,然后笔者就花了一天时间弄出来了。本以为这个东西很简单,实际上手的时候发现,还有很多逻辑需要处理,稍不注意就容易乱套。写个UI效果图大约只花了3个小时,但是处理逻辑就处理
本文向大家介绍Android 简易手势密码开源库详解,包括了Android 简易手势密码开源库详解的使用技巧和注意事项,需要的朋友参考一下 简介 本文介绍一个Android手势密码开源库的使用及实现的详细过程,该开源库主要实现以下几个功能: 支持手势密码的绘制,并支持密码保存功能,解锁时自动比对密码给出结果 封装了绘制密码的方法,比对两次密码是否一致,可以快捷地进行手势密码的设置 可以设置密码输入
本文向大家介绍Android自定义GestureDetector实现手势ImageView,包括了Android自定义GestureDetector实现手势ImageView的使用技巧和注意事项,需要的朋友参考一下 不说废话了,进入我们今天的主题吧。 先贴上前面内容的地址: Android手势ImageView三部曲(一) Android手势ImageView三部曲(二) Android手势Ima