手势解锁自定义View

  1 package com.rxx.view;
  2
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 import java.util.Timer;
  6 import java.util.TimerTask;
  7 import android.content.Context;
  8 import android.graphics.Canvas;
  9 import android.graphics.Color;
 10 import android.graphics.Paint;
 11 import android.graphics.Path;
 12 import android.util.AttributeSet;
 13 import android.view.MotionEvent;
 14 import android.view.View;
 15
 16 /**
 17  * 自定义锁屏View
 18  */
 19 public class GestureLockView extends View {
 20     /** 解锁密码key */
 21     private String key = "";
 22     private OnGestureFinishListener onGestureFinishListener;
 23
 24     /** 解锁圆点数组 */
 25     private LockCircle[] cycles;
 26     /** 存储触碰圆的序列 */
 27     private List<Integer> linedCycles = new ArrayList<Integer>();
 28
 29     // 画笔
 30     /** 空心外圆 */
 31     private Paint paintNormal;
 32     /** 点击后内部圆 */
 33     private Paint paintInnerCycle;
 34     /** 画路径 */
 35     private Paint paintLines;
 36     private Path linePath = new Path();
 37
 38     /** 当前手指X,Y位置 */
 39     private int eventX, eventY;
 40
 41     /** 能否操控界面绘画 */
 42     private boolean canContinue = true;
 43     /** 验证结果 */
 44     private boolean result;
 45     private Timer timer;
 46
 47     /** 未选中颜色 */
 48     private final int NORMAL_COLOR = Color.parseColor("#959BB4");
 49     /** 错误颜色 */
 50     private final int ERROE_COLOR = Color.parseColor("#FF2525"); // 正常外圆颜色
 51     /** 选中时颜色 */
 52     private final int TOUCH_COLOR = Color.parseColor("#409DE5"); // 选中内圆颜色
 53
 54     // =================================start=构造方法========================
 55     public GestureLockView(Context context, AttributeSet attrs, int defStyle) {
 56         super(context, attrs, defStyle);
 57         init();
 58     }
 59
 60     public GestureLockView(Context context, AttributeSet attrs) {
 61         this(context, attrs, 0);
 62     }
 63
 64     public GestureLockView(Context context) {
 65         this(context, null);
 66     }
 67
 68     // ===============================end=构造方法========================
 69
 70     /** 初始化 */
 71     public void init() {
 72         paintNormal = new Paint();
 73         paintNormal.setAntiAlias(true);
 74         paintNormal.setStrokeWidth(5);
 75         paintNormal.setStyle(Paint.Style.STROKE);
 76
 77         paintInnerCycle = new Paint();
 78         paintInnerCycle.setAntiAlias(true);
 79         paintInnerCycle.setStyle(Paint.Style.FILL);
 80
 81         paintLines = new Paint();
 82         paintLines.setAntiAlias(true);
 83         paintLines.setStyle(Paint.Style.STROKE);
 84         paintLines.setStrokeWidth(10);
 85
 86     }
 87
 88     @Override
 89     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 90         int specMode = MeasureSpec.getMode(widthMeasureSpec);
 91         int spceSize = MeasureSpec.getSize(widthMeasureSpec);
 92         heightMeasureSpec = MeasureSpec.makeMeasureSpec(
 93                 (int) (spceSize * 0.85 + 0.5f), specMode);
 94         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 95     }
 96
 97     @Override
 98     protected void onLayout(boolean changed, int left, int top, int right,
 99             int bottom) {
100         super.onLayout(changed, left, top, right, bottom);
101         int perWidthSize = getWidth() / 7;
102         int perHeightSize = getHeight() / 6;
103         /** 初始化圆的参数 */
104         if (cycles == null && (perWidthSize > 0) && (perHeightSize > 0)) {
105             cycles = new LockCircle[9];
106             for (int i = 0; i < 3; i++) {
107                 for (int j = 0; j < 3; j++) {
108                     LockCircle lockCircle = new LockCircle();
109                     lockCircle.setNum(i * 3 + j);
110                     lockCircle.setOx(perWidthSize * (j * 2 + 1.5f) + 0.5f);
111                     lockCircle.setOy(perHeightSize * (i * 2 + 1) + 0.5f);
112                     lockCircle.setR(perWidthSize * 0.6f);
113                     cycles[i * 3 + j] = lockCircle;
114                 }
115             }
116         }
117
118     }
119
120     public void setKey(String key) {
121         this.key = key;
122     }
123
124     public void setOnGestureFinishListener(
125             OnGestureFinishListener onGestureFinishListener) {
126         this.onGestureFinishListener = onGestureFinishListener;
127     }
128
129     /** 手势输入完成后回调接口 */
130     public interface OnGestureFinishListener {
131         /** 手势输入完成后回调函数 */
132         public void OnGestureFinish(boolean success, String key);
133     }
134
135     /** 监听手势 */
136     @Override
137     public boolean onTouchEvent(MotionEvent event) {
138         if (canContinue) {
139             switch (event.getAction()) {
140             case MotionEvent.ACTION_DOWN:
141             case MotionEvent.ACTION_MOVE:
142                 eventX = (int) event.getX();
143                 eventY = (int) event.getY();
144                 for (int i = 0; i < cycles.length; i++) {
145                     if (cycles[i].isPointIn(eventX, eventY)) {
146                         cycles[i].setOnTouch(true);
147                         if (!linedCycles.contains(cycles[i].getNum())) {
148                             linedCycles.add(cycles[i].getNum());
149                         }
150                     }
151                 }
152                 break;
153             case MotionEvent.ACTION_UP:
154                 // 手指离开暂停触碰
155                 canContinue = false;
156                 StringBuffer stringBuffer = new StringBuffer();
157                 for (int i = 0; i < linedCycles.size(); i++) {
158                     stringBuffer.append(linedCycles.get(i));
159                 }
160                 result = key.equals(stringBuffer.toString());
161                 if (onGestureFinishListener != null && linedCycles.size() > 0) {
162                     onGestureFinishListener.OnGestureFinish(result,
163                             stringBuffer.toString());
164                 }
165                 timer = new Timer();
166                 timer.schedule(new TimerTask() {
167                     @Override
168                     public void run() {
169                         eventX = eventY = 0;
170                         for (int i = 0; i < 9; i++) {
171                             cycles[i].setOnTouch(false);
172                         }
173                         linedCycles.clear();
174                         linePath.reset();
175                         canContinue = true;
176                         postInvalidate();// 在非ui线程刷新界面
177                     }
178                 }, 1000);
179                 break;
180             }
181             invalidate();
182         }
183         return true;
184     }
185
186     @Override
187     protected void onDraw(Canvas canvas) {
188         super.onDraw(canvas);
189         int cycleSize = cycles.length;
190         for (int i = 0; i < cycleSize; i++) {
191             // 画完并且错误
192             if (!canContinue && !result) {
193                 if (cycles[i].isOnTouch()) {
194                     drawInnerCycle(cycles[i], canvas, ERROE_COLOR);
195                     drawOutsideCycle(cycles[i], canvas, ERROE_COLOR);
196                 } else
197                     drawOutsideCycle(cycles[i], canvas, NORMAL_COLOR);
198             }
199             // 绘画中
200             else {
201                 if (cycles[i].isOnTouch()) {
202                     drawInnerCycle(cycles[i], canvas, TOUCH_COLOR);
203                     drawOutsideCycle(cycles[i], canvas, TOUCH_COLOR);
204                 } else
205                     drawOutsideCycle(cycles[i], canvas, NORMAL_COLOR);
206             }
207         }
208
209         if (!canContinue && !result) {
210             drawLine(canvas, ERROE_COLOR);
211         } else {
212             drawLine(canvas, TOUCH_COLOR);
213         }
214
215     }
216
217     /** 画空心圆 */
218     private void drawOutsideCycle(LockCircle lockCircle, Canvas canvas,
219             int color) {
220         paintNormal.setColor(color);
221         canvas.drawCircle(lockCircle.getOx(), lockCircle.getOy(),
222                 lockCircle.getR(), paintNormal);
223     }
224
225     /** 画横线 */
226     private void drawLine(Canvas canvas, int color) {
227         // 构建路径
228         linePath.reset();
229         if (linedCycles.size() > 0) {
230             int size = linedCycles.size();
231             for (int i = 0; i < size; i++) {
232                 int index = linedCycles.get(i);
233                 float x = cycles[index].getOx();
234                 float y = cycles[index].getOy();
235                 if (i == 0) {
236                     linePath.moveTo(x, y);
237                 } else {
238                     linePath.lineTo(x, y);
239                 }
240             }
241             if (canContinue) {
242                 linePath.lineTo(eventX, eventY);
243             } else {
244                 linePath.lineTo(
245                         cycles[linedCycles.get(linedCycles.size() - 1)].getOx(),
246                         cycles[linedCycles.get(linedCycles.size() - 1)].getOy());
247             }
248             paintLines.setColor(color);
249             canvas.drawPath(linePath, paintLines);
250         }
251     }
252
253     /** 画中心圆圆 */
254     private void drawInnerCycle(LockCircle myCycle, Canvas canvas, int color) {
255         paintInnerCycle.setColor(color);
256         canvas.drawCircle(myCycle.getOx(), myCycle.getOy(),
257                 myCycle.getR() / 3f, paintInnerCycle);
258     }
259
260     /**
261      * 每个圆点类
262      */
263     class LockCircle {
264         /** 圆心横坐标 */
265         private float ox;
266         /** 圆心纵坐标 */
267         private float oy;
268         /** 半径长度 */
269         private float r;
270         /** 代表数值 */
271         private Integer num;
272         /** 是否选择:false=未选中 */
273         private boolean onTouch;
274
275         public float getOx() {
276             return ox;
277         }
278
279         public void setOx(float ox) {
280             this.ox = ox;
281         }
282
283         public float getOy() {
284             return oy;
285         }
286
287         public void setOy(float oy) {
288             this.oy = oy;
289         }
290
291         public void setOy(int oy) {
292             this.oy = oy;
293         }
294
295         public float getR() {
296             return r;
297         }
298
299         public void setR(float r) {
300             this.r = r;
301         }
302
303         public Integer getNum() {
304             return num;
305         }
306
307         public void setNum(Integer num) {
308             this.num = num;
309         }
310
311         public boolean isOnTouch() {
312             return onTouch;
313         }
314
315         public void setOnTouch(boolean onTouch) {
316             this.onTouch = onTouch;
317         }
318
319         /** 判读传入位置是否在圆心内部 */
320         public boolean isPointIn(int x, int y) {
321             double distance = Math.sqrt((x - ox) * (x - ox) + (y - oy)
322                     * (y - oy));
323             return distance < r;
324         }
325     }
326 }
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="fill_parent"
 3     android:layout_height="fill_parent"
 4     android:background="#232736"
 5     android:gravity="center"
 6     android:orientation="vertical" >
 7
 8     <!-- 小头像 -->
 9     <ImageView
10         android:layout_width="70dp"
11         android:layout_height="70dp"
12         android:src="@drawable/tempfenlei" />
13
14     <TextView
15         android:id="@+id/textview"
16         android:layout_width="wrap_content"
17         android:layout_height="wrap_content"
18         android:layout_marginTop="10dp"
19         android:text=""
20         android:textColor="#FF2525"
21         android:textSize="16sp"
22         android:visibility="invisible" />
23
24     <com.rxx.view.GestureLockView
25         android:id="@+id/gestureLockView"
26         android:layout_width="wrap_content"
27         android:layout_height="wrap_content" />
28
29     <LinearLayout
30         android:layout_width="fill_parent"
31         android:layout_height="wrap_content"
32         android:orientation="horizontal"
33         android:padding="10dp" >
34
35         <TextView
36             android:layout_width="fill_parent"
37             android:layout_height="wrap_content"
38             android:layout_weight="1"
39             android:gravity="center"
40             android:text="管理手势密码"
41             android:textColor="#585C6E"
42             android:textSize="16sp" />
43
44         <TextView
45             android:layout_width="fill_parent"
46             android:layout_height="wrap_content"
47             android:layout_weight="1"
48             android:gravity="center"
49             android:text="登陆其他账号"
50             android:textColor="#585C6E"
51             android:textSize="16sp" />
52     </LinearLayout>
53
54 </LinearLayout>
 1 package com.rxx.gesturelockdemo;
 2
 3 import android.app.Activity;
 4 import android.graphics.Color;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.view.animation.Animation;
 8 import android.view.animation.TranslateAnimation;
 9 import android.widget.TextView;
10
11 import com.rxx.view.GestureLockView;
12 import com.rxx.view.GestureLockView.OnGestureFinishListener;
13
14 public class MainActivity extends Activity {
15
16     private GestureLockView gestureLockView;
17     private TextView textview;
18     private Animation animation;
19
20     @Override
21     protected void onCreate(Bundle savedInstanceState) {
22         super.onCreate(savedInstanceState);
23         setContentView(R.layout.activity_main);
24         init();
25     }
26
27     /** 初始化 */
28     public void init() {
29         gestureLockView = (GestureLockView) findViewById(R.id.gestureLockView);
30         textview = (TextView) findViewById(R.id.textview);
31         animation = new TranslateAnimation(-20, 20, 0, 0);
32         animation.setDuration(50);
33         animation.setRepeatCount(2);
34         animation.setRepeatMode(Animation.REVERSE);
35         // 设置密码
36         gestureLockView.setKey("1");
37         // 手势完成后回调
38         gestureLockView
39                 .setOnGestureFinishListener(new OnGestureFinishListener() {
40                     @Override
41                     public void OnGestureFinish(boolean success, String key) {
42                         if (success) {
43                             textview.setTextColor(Color.parseColor("#FFFFFF"));
44                             textview.setVisibility(View.VISIBLE);
45                             textview.setText("密码正确!");
46                             textview.startAnimation(animation);
47                         } else {
48                             textview.setTextColor(Color.parseColor("#FF2525"));
49                             textview.setVisibility(View.VISIBLE);
50                             textview.setText("密码错误!");
51                             textview.startAnimation(animation);
52                         }
53                     }
54                 });
55     }
56 }
时间: 2024-08-29 13:26:14

手势解锁自定义View的相关文章

九点(九宫格)式手势解锁自定义view

周末闲着没事,写了个手势解锁的view,实现起来也蛮快的,半天多一点时间就完事.把源码和资源贴出来,给大家分享,希望对大家有用. 效果,就跟手机上的九点手势解锁一样,上个图吧: 过程嘛感觉确实没啥好讲的了,涉及的知识以前的博客都说过了,无非就是canva,paint,touch事件这些,画画圆圈画画线条,剩下的就是细节处理逻辑了.都在代码里,所以这里就主要是贴资源吧. 这个自定义view就一个类,源码如下: package com.cc.library.view; import android.

Android Matrix手势缩放自定义view 不止于Imageview

转载请注明出处:http://blog.csdn.net/coderyue/article/details/51397409 之前写过一篇文章Android TextView 横竖排切换(字方向不变) 是自定义了一个LinearLayout, 实现了当然还不够, 还要对它进行操作, 平移,旋转 and 缩放, 相信很多小伙伴都知道对图片的平移等等操作最好用的就是矩阵了,因为有个方法叫做imageview.setImageMatrix(matrix), 直接构造一个矩阵对象然后设置到图片上就进行相

Android进阶之自定义View实战(二)九宫格手势解锁实现

一.引言 在上篇博客Android进阶之自定义View实战(一)仿iOS UISwitch控件实现中我们主要介绍了自定义View的最基本的实现方法.作为自定义View的入门篇,仅仅介绍了Canvas的基本使用方法,而对用户交互层面仅仅处理了单击事件接口,在实际的业务中,常常涉及到手势操作,本篇博客以九宫格手势解锁View为例,来说明自定义View如何根据需求处理用户的手势操作.虽然九宫格手势解锁自定义View网上资料有很多,实现原理大同小异,但这里我只是根据自己觉得最优的思路来实现它,目的是让更

android自定义手势解锁View

有时候为了程序的安全性,我们经常要采取一些安全措施,就像我们常用的支付宝那样,隔一定的时间再回到应用程序时会让用户利用手势去解锁应用程序,最近由于项目需求,也要求做这样一个功能,当用户切出本应用程序15分钟后回来,让用户手势解锁,整个需求的难点就在如何实现这个手势锁,开始一点头绪也没有,没有一点思路去实现这个手势解锁功能,在google了一番后看了一篇非常好的博客后,按照博主的思路的确是可以实现一个十分不错的手势锁View,也参考了下那位大神的代码,下面是我根据他的思路和代码片段实现的一个自定义

自定义手势解锁锁控件

一.控件的使用 模仿市面上app的手势解锁功能,实现的小控件,将控件封装到了一个UIView上 二.核心原理技术 1.触摸事件 (1)UIView的触摸三个触摸响应事件:开始.移动.结束 (2)CGRectContainsPoint 判断触摸点的位置 2.Quartz2D绘图 (1)drawRect 的重绘 (2)UIBezierPath 贝塞尔曲线 3.block成功和失败的回调 三.实现思路 1.解锁键盘中的9个小图标,会根据验证过程而变化颜色,所以考虑用UIButton实现,因为UIBut

自定义View实现手势监听

下面是我自定义的view,主要是实现左右滑动 要实现手势监听,首先要实现OnGestureListener接口 其次是实例化一个GestureDetector:mDetector = new GestureDetector(context, this); 如果只是简单的实现OnGestureListener的方法,是不能实现监听效果, 我们要将onDown , onScroll的返回值改为true,自定义view的clickable属性为true. 除此之外,我们要重写自定义view的onTou

iOS开发之手势解锁

本文主要介绍通过手势识别实现手势解锁功能,这个方法被广泛用于手机解锁,密码验证,快捷支付等功能实现.事例效果如下所示. 首先,我们先分析功能的实现过程,首先我们需要先看大致的实现过程: 1.加载九宫格页面 2.实现按钮被点击及滑动过程中按钮状态的改变 3.实现滑动过程中的连线 4.绘制完毕后判定密码是否正确, 5.密码判定后实现跳转. 下面我们就来用代码实现上述五个过程. 1.加载九宫格界面 1.1九宫格内控件的分布 3*3 ,我们可以自定义view(包含3*3个按钮),添加到viewContr

手势解锁

ViewController.m // //  ViewController.m //  6A08.手势解锁 // //  Created by huan on 16/2/1. //  Copyright © 2016年 huanxi. All rights reserved. // #import "ViewController.h" #import "CZLockView.h" @interface ViewController () @end @impleme

手势解锁步骤的基本思路

------------- 基本思路 -------------- - 1. 搭建界面,九宫格算法 - 2. 处理按钮选中状态 - 3. 按钮之间画线 - 4. 手指和按钮之间画线 - 5. 判断解锁密码是否正确 ------------- 基本思路 -------------- 1. 拖拽图片素材 2. 设置控制器 view 的背景色为"HomeButtomBG"图片平铺后的效果 self.view.backgroundColor = [UIColor colorWithPatter