栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

android自定义View实现手势解锁

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

android自定义View实现手势解锁

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

这是自定义View的初始效果图:

以下是绘制手势时的效果图:

下面是实现的demo代码:

package com.example.gesturelock; 
 
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; 
 
import com.example.gesturelock.GestureLockView.OnGestureFinishListener; 
 
public class MyGestureLockView extends View { 
 
   
  private Paint paintNormal; 
  private Paint paintOnTouch; 
  private Paint paintInnerCycle; 
  private Paint paintLines; 
  private Paint paintKeyError; 
 
  private MyCycle[] cycles; 
  private Path linePath = new Path(); 
  private List linedCycles = new ArrayList(); 
  private onGestureFinishListener onGestureFinishListener; 
  private String key; 
  private int eventX, eventY; 
  private boolean canContinue = true; 
  private boolean result; 
  private Timer timer; 
 
   
  private int OUT_CYCLE_NORMAL = Color.rgb(108, 119, 138); // ������Բ��ɫ 
  private int OUT_CYCLE_onTOUCH = Color.rgb(025, 066, 103); // ѡ����Բ��ɫ 
  private int INNER_CYCLE_onTOUCH = Color.rgb(002, 210, 255); // ѡ����Բ��ɫ 
  private int LINE_COLOR = Color.argb(127, 002, 210, 255); // ��������ɫ 
  private int ERROR_COLOR = Color.argb(127, 255, 000, 000); 
 
  public void setonGestureFinishListener( 
      onGestureFinishListener onGestureFinishListener) { 
    this.onGestureFinishListener = onGestureFinishListener; 
  } 
 
  public void setKey(String key) { 
    this.key = key; 
  } 
 
  public MyGestureLockView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(); 
  } 
 
  public MyGestureLockView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
  } 
 
  public MyGestureLockView(Context context) { 
    super(context); 
    init(); 
  } 
 
  private void init() { 
 
    paintNormal = new Paint(); 
    paintNormal.setAntiAlias(true); 
    paintNormal.setStrokeWidth(3); 
    paintNormal.setStyle(Paint.Style.STROKE); 
 
    paintonTouch = new Paint(); 
    paintOnTouch.setAntiAlias(true); 
    paintOnTouch.setStrokeWidth(3); 
    paintOnTouch.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(6); 
 
    paintKeyError = new Paint(); 
    paintKeyError.setAntiAlias(true); 
    paintKeyError.setStyle(Paint.Style.STROKE); 
    paintKeyError.setStrokeWidth(3); 
 
  } 
 
  @Override 
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    // TODO Auto-generated method stub 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
  } 
 
  @Override 
  protected void onLayout(boolean changed, int left, int top, int right, 
      int bottom) { 
    // TODO Auto-generated method stub 
    super.onLayout(changed, left, top, right, bottom); 
    int perSize = 0; 
    if (cycles == null && (perSize = getWidth() / 6) > 0) { 
 
      cycles = new MyCycle[9]; 
      for (int i = 0; i < 3; i++) { 
 for (int j = 0; j < 3; j++) { 
   MyCycle cycle = new MyCycle(); 
   cycle.setNum(i * 3 + j); 
   cycle.setOx(perSize * (j * 2 + 1)); 
   cycle.setOy(perSize * (i * 2 + 1)); 
   cycle.setR(perSize * 0.5f); 
   cycles[i * 3 + j] = cycle; 
 } 
      } 
    } 
  } 
 
   
  @Override 
  protected void onDraw(Canvas canvas) { 
    // TODO Auto-generated method stub 
    super.onDraw(canvas); 
    for (int i = 0; i < cycles.length; i++) { 
 
      if (!canContinue && !result) { 
 paintOnTouch.setColor(ERROR_COLOR); 
 paintInnerCycle.setColor(ERROR_COLOR); 
 paintLines.setColor(ERROR_COLOR); 
      } else if (cycles[i].isonTouch()) { 
 paintOnTouch.setColor(OUT_CYCLE_ONTOUCH); 
 paintInnerCycle.setColor(INNER_CYCLE_ONTOUCH); 
 paintLines.setColor(LINE_COLOR); 
      } else { 
 paintNormal.setColor(OUT_CYCLE_NORMAL); 
 paintInnerCycle.setColor(INNER_CYCLE_ONTOUCH); 
 paintLines.setColor(LINE_COLOR); 
      } 
 
      if (cycles[i].isonTouch()) { 
 canvas.drawCircle(cycles[i].getOx(), cycles[i].getOy(), 
     cycles[i].getR(), paintOnTouch); 
 drawInnerBuleCycle(cycles[i], canvas); 
      } else { 
 
 canvas.drawCircle(cycles[i].getOx(), cycles[i].getOy(), 
     cycles[i].getR(), paintNormal); 
      } 
    } 
    drawLine(canvas); 
  } 
 
   
  private void drawInnerBuleCycle(MyCycle cycle, Canvas canvas) { 
    canvas.drawCircle(cycle.getOx(), cycle.getOy(), cycle.getR() / 3, 
 paintInnerCycle); 
  } 
 
  private void drawLine(Canvas canvas) { 
    linePath.reset(); 
    if (linedCycles.size() > 0) { 
      for (int i = 0; i < linedCycles.size(); i++) { 
 int index = linedCycles.get(i); 
 if (i == 0) { 
   // 设置为整条路径的起点 
   linePath.moveTo(cycles[index].getOx(), cycles[i].getOy()); 
 } else { 
   linePath.lineTo(cycles[i].getOx(), cycles[i].getOy()); 
 } 
      } 
      linePath.lineTo(eventX, eventY); 
      canvas.drawPath(linePath, paintLines); 
    } 
  } 
 
   
  @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 sb = new StringBuffer(); 
 for (int i = 0; i < linedCycles.size(); i++) { 
   sb.append(linedCycles.get(i)); 
 } 
 result = key.equals(sb.toString()); 
 if (onGestureFinishListener != null) { 
   onGestureFinishListener.onGestureFinish(result); 
 } 
 timer = new Timer(); 
 timer.schedule(new TimerTask() { 
 
   @Override 
   public void run() { 
     // 回到初始状态 
     eventX = eventY = 0; 
     for (int i = 0; i < cycles.length; i++) { 
cycles[i].setonTouch(false); 
     } 
     linedCycles.clear(); 
     linePath.reset(); 
     canContinue = true; 
     postInvalidate(); 
   } 
 }, 1000); 
 break; 
      } 
    } 
    invalidate(); 
    return true; 
  } 
} 

自定义圆类:

package com.example.gesturelock; 
 
public class MyCycle { 
  private int ox;     // Բ�ĺ����� 
  private int oy;     // Բ�������� 
  private float r;     // �뾶���� 
  private Integer num;   // ������ֵ 
  private boolean onTouch; // false=δѡ�� 
  public int getOx() { 
    return ox; 
  } 
  public void setOx(int ox) { 
    this.ox = ox; 
  } 
  public int getOy() { 
    return 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; 
  } 
} 

思路:

     1.自定义一个 View和MyCircle类,将九个MyCircle类的实例绘制到View中.

     2.处理onTouch事件,根据不同的事件修改MyCircle实例的状态,并调用更新invaildate更新View

     3.重写onDraw()方法,根据不同的状态去重新绘制整个View

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/156043.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号