手势解锁自定义View

手势解锁自定义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 }

 

你可能感兴趣的:(view)