手势解锁自定义View
package com.rxx.view; import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; /**
* 自定义锁屏View
*/
public class GestureLockView extends View {
/** 解锁密码key */
private String key = "";
private OnGestureFinishListener onGestureFinishListener; /** 解锁圆点数组 */
private LockCircle[] cycles;
/** 存储触碰圆的序列 */
private List<Integer> linedCycles = new ArrayList<Integer>(); // 画笔
/** 空心外圆 */
private Paint paintNormal;
/** 点击后内部圆 */
private Paint paintInnerCycle;
/** 画路径 */
private Paint paintLines;
private Path linePath = new Path(); /** 当前手指X,Y位置 */
private int eventX, eventY; /** 能否操控界面绘画 */
private boolean canContinue = true;
/** 验证结果 */
private boolean result;
private Timer timer; /** 未选中颜色 */
private final int NORMAL_COLOR = Color.parseColor("#959BB4");
/** 错误颜色 */
private final int ERROE_COLOR = Color.parseColor("#FF2525"); // 正常外圆颜色
/** 选中时颜色 */
private final int TOUCH_COLOR = Color.parseColor("#409DE5"); // 选中内圆颜色 // =================================start=构造方法========================
public GestureLockView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
} public GestureLockView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public GestureLockView(Context context) {
this(context, null);
} // ===============================end=构造方法======================== /** 初始化 */
public void init() {
paintNormal = new Paint();
paintNormal.setAntiAlias(true);
paintNormal.setStrokeWidth(5);
paintNormal.setStyle(Paint.Style.STROKE); paintInnerCycle = new Paint();
paintInnerCycle.setAntiAlias(true);
paintInnerCycle.setStyle(Paint.Style.FILL); paintLines = new Paint();
paintLines.setAntiAlias(true);
paintLines.setStyle(Paint.Style.STROKE);
paintLines.setStrokeWidth(10); } @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int spceSize = MeasureSpec.getSize(widthMeasureSpec);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(
(int) (spceSize * 0.85 + 0.5f), specMode);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} @Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
int perWidthSize = getWidth() / 7;
int perHeightSize = getHeight() / 6;
/** 初始化圆的参数 */
if (cycles == null && (perWidthSize > 0) && (perHeightSize > 0)) {
cycles = new LockCircle[9];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
LockCircle lockCircle = new LockCircle();
lockCircle.setNum(i * 3 + j);
lockCircle.setOx(perWidthSize * (j * 2 + 1.5f) + 0.5f);
lockCircle.setOy(perHeightSize * (i * 2 + 1) + 0.5f);
lockCircle.setR(perWidthSize * 0.6f);
cycles[i * 3 + j] = lockCircle;
}
}
} } public void setKey(String key) {
this.key = key;
} public void setOnGestureFinishListener(
OnGestureFinishListener onGestureFinishListener) {
this.onGestureFinishListener = onGestureFinishListener;
} /** 手势输入完成后回调接口 */
public interface OnGestureFinishListener {
/** 手势输入完成后回调函数 */
public void OnGestureFinish(boolean success, String key);
} /** 监听手势 */
@Override
public boolean onTouchEvent(MotionEvent event) {
if (canContinue) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
eventX = (int) event.getX();
eventY = (int) event.getY();
for (int i = 0; i < cycles.length; i++) {
if (cycles[i].isPointIn(eventX, eventY)) {
cycles[i].setOnTouch(true);
if (!linedCycles.contains(cycles[i].getNum())) {
linedCycles.add(cycles[i].getNum());
}
}
}
break;
case MotionEvent.ACTION_UP:
// 手指离开暂停触碰
canContinue = false;
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < linedCycles.size(); i++) {
stringBuffer.append(linedCycles.get(i));
}
result = key.equals(stringBuffer.toString());
if (onGestureFinishListener != null && linedCycles.size() > 0) {
onGestureFinishListener.OnGestureFinish(result,
stringBuffer.toString());
}
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
eventX = eventY = 0;
for (int i = 0; i < 9; i++) {
cycles[i].setOnTouch(false);
}
linedCycles.clear();
linePath.reset();
canContinue = true;
postInvalidate();// 在非ui线程刷新界面
}
}, 1000);
break;
}
invalidate();
}
return true;
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int cycleSize = cycles.length;
for (int i = 0; i < cycleSize; i++) {
// 画完并且错误
if (!canContinue && !result) {
if (cycles[i].isOnTouch()) {
drawInnerCycle(cycles[i], canvas, ERROE_COLOR);
drawOutsideCycle(cycles[i], canvas, ERROE_COLOR);
} else
drawOutsideCycle(cycles[i], canvas, NORMAL_COLOR);
}
// 绘画中
else {
if (cycles[i].isOnTouch()) {
drawInnerCycle(cycles[i], canvas, TOUCH_COLOR);
drawOutsideCycle(cycles[i], canvas, TOUCH_COLOR);
} else
drawOutsideCycle(cycles[i], canvas, NORMAL_COLOR);
}
} if (!canContinue && !result) {
drawLine(canvas, ERROE_COLOR);
} else {
drawLine(canvas, TOUCH_COLOR);
} } /** 画空心圆 */
private void drawOutsideCycle(LockCircle lockCircle, Canvas canvas,
int color) {
paintNormal.setColor(color);
canvas.drawCircle(lockCircle.getOx(), lockCircle.getOy(),
lockCircle.getR(), paintNormal);
} /** 画横线 */
private void drawLine(Canvas canvas, int color) {
// 构建路径
linePath.reset();
if (linedCycles.size() > 0) {
int size = linedCycles.size();
for (int i = 0; i < size; i++) {
int index = linedCycles.get(i);
float x = cycles[index].getOx();
float y = cycles[index].getOy();
if (i == 0) {
linePath.moveTo(x, y);
} else {
linePath.lineTo(x, y);
}
}
if (canContinue) {
linePath.lineTo(eventX, eventY);
} else {
linePath.lineTo(
cycles[linedCycles.get(linedCycles.size() - 1)].getOx(),
cycles[linedCycles.get(linedCycles.size() - 1)].getOy());
}
paintLines.setColor(color);
canvas.drawPath(linePath, paintLines);
}
} /** 画中心圆圆 */
private void drawInnerCycle(LockCircle myCycle, Canvas canvas, int color) {
paintInnerCycle.setColor(color);
canvas.drawCircle(myCycle.getOx(), myCycle.getOy(),
myCycle.getR() / 3f, paintInnerCycle);
} /**
* 每个圆点类
*/
class LockCircle {
/** 圆心横坐标 */
private float ox;
/** 圆心纵坐标 */
private float oy;
/** 半径长度 */
private float r;
/** 代表数值 */
private Integer num;
/** 是否选择:false=未选中 */
private boolean onTouch; public float getOx() {
return ox;
} public void setOx(float ox) {
this.ox = ox;
} public float getOy() {
return oy;
} public void setOy(float oy) {
this.oy = oy;
} public void setOy(int oy) {
this.oy = oy;
} public float getR() {
return r;
} public void setR(float r) {
this.r = r;
} public Integer getNum() {
return num;
} public void setNum(Integer num) {
this.num = num;
} public boolean isOnTouch() {
return onTouch;
} public void setOnTouch(boolean onTouch) {
this.onTouch = onTouch;
} /** 判读传入位置是否在圆心内部 */
public boolean isPointIn(int x, int y) {
double distance = Math.sqrt((x - ox) * (x - ox) + (y - oy)
* (y - oy));
return distance < r;
}
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#232736"
android:gravity="center"
android:orientation="vertical" > <!-- 小头像 -->
<ImageView
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/tempfenlei" /> <TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text=""
android:textColor="#FF2525"
android:textSize="16sp"
android:visibility="invisible" /> <com.rxx.view.GestureLockView
android:id="@+id/gestureLockView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp" > <TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="管理手势密码"
android:textColor="#585C6E"
android:textSize="16sp" /> <TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="登陆其他账号"
android:textColor="#585C6E"
android:textSize="16sp" />
</LinearLayout> </LinearLayout>
package com.rxx.gesturelockdemo; import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.TextView; import com.rxx.view.GestureLockView;
import com.rxx.view.GestureLockView.OnGestureFinishListener; public class MainActivity extends Activity { private GestureLockView gestureLockView;
private TextView textview;
private Animation animation; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
} /** 初始化 */
public void init() {
gestureLockView = (GestureLockView) findViewById(R.id.gestureLockView);
textview = (TextView) findViewById(R.id.textview);
animation = new TranslateAnimation(-20, 20, 0, 0);
animation.setDuration(50);
animation.setRepeatCount(2);
animation.setRepeatMode(Animation.REVERSE);
// 设置密码
gestureLockView.setKey("1");
// 手势完成后回调
gestureLockView
.setOnGestureFinishListener(new OnGestureFinishListener() {
@Override
public void OnGestureFinish(boolean success, String key) {
if (success) {
textview.setTextColor(Color.parseColor("#FFFFFF"));
textview.setVisibility(View.VISIBLE);
textview.setText("密码正确!");
textview.startAnimation(animation);
} else {
textview.setTextColor(Color.parseColor("#FF2525"));
textview.setVisibility(View.VISIBLE);
textview.setText("密码错误!");
textview.startAnimation(animation);
}
}
});
}
}
手势解锁自定义View的更多相关文章
- 【Android - 自定义View】之自定义九宫格手势解锁控件
首先来介绍一下这个自定义View: (1)这个自定义View的名称叫做 LockView ,继承自View类: (2)这个自定义View实现了应用中常见的九宫格手势解锁功能,可以用于保证应用安全: ( ...
- Quartz2D复习(二) --- 手势解锁
这次支付宝手机客户端升级,把手势解锁那个功能去掉了,引起很多人的抱怨,觉得少了手势解锁的保护,个人信息容易泄漏了... 那么手势解锁功能是怎么是实现的呢,这里使用Quart2D来简单模拟一下, 先看下 ...
- iOS--开发之手势解锁
本文主要介绍通过手势识别实现手势解锁功能,这个方法被广泛用于手机解锁,密码验证,快捷支付等功能实现.事例效果如下所示. 首先,我们先分析功能的实现过程,首先我们需要先看大致的实现过程: 1.加载九宫格 ...
- 2016-1-10 手势解锁demo的实现
一:实现自定义view,在.h,.m文件中代码如下: #import <UIKit/UIKit.h> @class ZLLockView; @protocol ZLLockViewDele ...
- [iOS UI进阶 - 5.0] 手势解锁Demo
A.需求 1.九宫格手势解锁 2.使用了绘图和手势事件 code source: https://github.com/hellovoidworld/GestureUnlockDemo B ...
- iOS-高仿支付宝手势解锁(九宫格)
概述 高仿支付宝手势解锁, 通过手势枚举去实现手势密码相对应操作. 详细 代码下载:http://www.demodashi.com/demo/10706.html 基上篇[TouchID 指纹解锁] ...
- [转]Android自定义控件三部曲系列完全解析(动画, 绘图, 自定义View)
来源:http://blog.csdn.net/harvic880925/article/details/50995268 一.自定义控件三部曲之动画篇 1.<自定义控件三部曲之动画篇(一)—— ...
- SJGestureUnlock快速集成手势解锁
前言:如果页面显示不完整或图片看不了还请移步:简书 SJGestureUnlock.h 常用自定义属性 @interface SJGestureUnlock : UIView @property (n ...
- Android自定义View的三种实现方式
在毕设项目中多处用到自定义控件,一直打算总结一下自定义控件的实现方式,今天就来总结一下吧.在此之前学习了郭霖大神博客上面关于自定义View的几篇博文,感觉受益良多,本文中就参考了其中的一些内容. 总结 ...
随机推荐
- hdu 3595 GG and MM 博弈论
同时进行,必须操作这就是Every-SG的特点 同样在贾志豪的论文中有提到这种游戏:组合游戏略述——浅谈SG游戏的若干拓展及变形 其中这个游戏特点不仅有必胜和必败,而且有时间长短的博弈,对于自己必胜的 ...
- java split IP地址要用双斜杠
示例代码: public void test() { String address = "11.12.13.14:800"; System.out.println(address. ...
- Project Euler 94:Almost equilateral triangles 几乎等边的三角形
Almost equilateral triangles It is easily proved that no equilateral triangle exists with integral l ...
- [mock]8月8日
第一题是整数的方阵,求其中的子方阵,和最大.返回最大和以及子方阵宽度.因为做了topcoder的题,所以比较顺手,O(n^3)的复杂度. pair<int,int> maxiSum(vec ...
- [topcoder]BoxesDiv2
https://community.topcoder.com/stat?c=problem_statement&pm=13192 #include <vector> #includ ...
- java 泛型类
Java泛型中的标记符含义: E - Element (在集合中使用,因为集合中存放的是元素) T - Type(Java 类) K - Key(键) V - Value(值) N - Numbe ...
- 64位下好神奇啊(增加了PatchGuard技术保护自己,SSDT是相对地址,参数通过寄存器与rdi来传递)
近期可能会有一个64位平台的驱动开发任务,找了些资料,对64位平台下的驱动开发略知一二了,好神奇. 一.在64位系统下,有一项PatchGuard技术,它是微软为了防止自己的代码被Patch,进而影响 ...
- iOS 相机和相册使用授权
1.判断用户是否有权限访问相册 授权一次后,不在提示是否授权 #import <AssetsLibrary/AssetsLibrary.h> ALAuthorizationStatus a ...
- 80. Remove Duplicates from Sorted Array II
题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...
- Ubuntu 64位系统安装StarUML之最佳实践
preview 相信很多使用Ubuntu的哥们在安装StarUML或者其他软件时都会遇到要求libgcrypt11的依赖.而遗憾的时,这个东西很多人根本找不到. 我将它分享到百度网盘,mark. 一. ...