当前位置: 移动技术网 > 移动技术>移动开发>Android > 超实用的Android手势锁制作实例教程

超实用的Android手势锁制作实例教程

2019年07月24日  | 移动技术网移动技术  | 我要评论

今天偶遇以github上gesturelock关于手势锁的一个例子(有兴趣的去搜索下看看),于是下载下来研究,无奈基本没有注释,代码上存在一些问题(当设置gravity=center_vertical无法进行手势选择,无意中发现的),于是借鉴这位仁兄的代码,自己重写写了一个,修复了一些问题,加入一些基本的自定义属性,在此先感谢这位兄弟~。
先上图,默认效果图:

当然可以自定义数量啊,颜色神马的,自定义效果图:

2016426162442168.gif (441×443)

如果你有艺术细胞,可以给我推荐几个颜色,无奈个人审美有问题~

1、整体思路
a、自定义了一个relativelayout(gesturelockviewgroup)在里面会根据传入的每行的个数,生成多个gesturelockview(就是上面一个个小圈圈),然后会自动进行布局,里面的宽度,间距,内圆的直径,箭头的大小神马的都是百分比实现的,所以大胆的设置你喜欢的个数,只要你没有密集恐惧症~
b、gesturelockview有三个状态,没有手指触碰、手指触碰、和手指抬起,会根据这三个状态绘制不同的效果,以及抬起时的小箭头需要旋转的角度,会根据用户选择的gesturelockview,进行计算,在gesturelockviewgroup为每个gesturelockview设置
c、gesturelockviewgroup主要就是判断用户action_move,action_down , action_up时改变选中的gesturelockview的状态,并且记录下来,提供一定的回调。
下面开始看代码:

2、声明一些用户可以设置的属性:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
 
  <attr name="color_no_finger_inner_circle" format="color" /> 
  <attr name="color_no_finger_outer_circle" format="color" /> 
  <attr name="color_finger_on" format="color" /> 
  <attr name="color_finger_up" format="color" /> 
  <attr name="count" format="integer" /> 
  <attr name="trytimes" format="integer" /> 
 
  <declare-styleable name="gesturelockviewgroup"> 
    <attr name="color_no_finger_inner_circle" /> 
    <attr name="color_no_finger_outer_circle" /> 
    <attr name="color_finger_on" /> 
    <attr name="color_finger_up" /> 
    <attr name="count" /> 
    <attr name="trytimes" /> 
  </declare-styleable> 
 
</resources> 

用户可以用过在xml文件中设置这些属性,改变外观,最多尝试次数以及数量等。

3、gesturelockview

package com.zhy.zhy_gesturelockview.view; 
 
import android.content.context; 
import android.graphics.canvas; 
import android.graphics.paint; 
import android.graphics.paint.style; 
import android.graphics.path; 
import android.view.view; 
 
public class gesturelockview extends view 
{ 
  private static final string tag = "gesturelockview"; 
  /** 
   * gesturelockview的三种状态 
   */ 
  enum mode 
  { 
    status_no_finger, status_finger_on, status_finger_up; 
  } 
 
  /** 
   * gesturelockview的当前状态 
   */ 
  private mode mcurrentstatus = mode.status_no_finger; 
   
  /** 
   * 宽度 
   */ 
  private int mwidth; 
  /** 
   * 高度 
   */ 
  private int mheight; 
  /** 
   * 外圆半径 
   */ 
  private int mradius; 
  /** 
   * 画笔的宽度 
   */ 
  private int mstrokewidth = 2; 
 
  /** 
   * 圆心坐标 
   */ 
  private int mcenterx; 
  private int mcentery; 
  private paint mpaint; 
 
  /** 
   * 箭头(小三角最长边的一半长度 = marrawrate * mwidth / 2 ) 
   */ 
  private float marrowrate = 0.333f; 
  private int marrowdegree = -1; 
  private path marrowpath; 
  /** 
   * 内圆的半径 = minnercircleradiusrate * mradus 
   * 
   */ 
  private float minnercircleradiusrate = 0.3f; 
 
  /** 
   * 四个颜色,可由用户自定义,初始化时由gesturelockviewgroup传入 
   */ 
  private int mcolornofingerinner; 
  private int mcolornofingeroutter; 
  private int mcolorfingeron; 
  private int mcolorfingerup; 
 
  public gesturelockview(context context , int colornofingerinner , int colornofingeroutter , int colorfingeron , int colorfingerup ) 
  { 
    super(context); 
    this.mcolornofingerinner = colornofingerinner; 
    this.mcolornofingeroutter = colornofingeroutter; 
    this.mcolorfingeron = colorfingeron; 
    this.mcolorfingerup = colorfingerup; 
    mpaint = new paint(paint.anti_alias_flag); 
    marrowpath = new path(); 
 
  } 
 
  @override 
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) 
  { 
    super.onmeasure(widthmeasurespec, heightmeasurespec); 
 
    mwidth = measurespec.getsize(widthmeasurespec); 
    mheight = measurespec.getsize(heightmeasurespec); 
 
    // 取长和宽中的小值 
    mwidth = mwidth < mheight ? mwidth : mheight; 
    mradius = mcenterx = mcentery = mwidth / 2; 
    mradius -= mstrokewidth / 2; 
 
    // 绘制三角形,初始时是个默认箭头朝上的一个等腰三角形,用户绘制结束后,根据由两个gesturelockview决定需要旋转多少度 
    float marrowlength = mwidth / 2 * marrowrate; 
    marrowpath.moveto(mwidth / 2, mstrokewidth + 2); 
    marrowpath.lineto(mwidth / 2 - marrowlength, mstrokewidth + 2 
        + marrowlength); 
    marrowpath.lineto(mwidth / 2 + marrowlength, mstrokewidth + 2 
        + marrowlength); 
    marrowpath.close(); 
    marrowpath.setfilltype(path.filltype.winding); 
 
  } 
 
  @override 
  protected void ondraw(canvas canvas) 
  { 
 
    switch (mcurrentstatus) 
    { 
    case status_finger_on: 
 
      // 绘制外圆 
      mpaint.setstyle(style.stroke); 
      mpaint.setcolor(mcolorfingeron); 
      mpaint.setstrokewidth(2); 
      canvas.drawcircle(mcenterx, mcentery, mradius, mpaint); 
      // 绘制内圆 
      mpaint.setstyle(style.fill); 
      canvas.drawcircle(mcenterx, mcentery, mradius 
          * minnercircleradiusrate, mpaint); 
      break; 
    case status_finger_up: 
      // 绘制外圆 
      mpaint.setcolor(mcolorfingerup); 
      mpaint.setstyle(style.stroke); 
      mpaint.setstrokewidth(2); 
      canvas.drawcircle(mcenterx, mcentery, mradius, mpaint); 
      // 绘制内圆 
      mpaint.setstyle(style.fill); 
      canvas.drawcircle(mcenterx, mcentery, mradius 
          * minnercircleradiusrate, mpaint); 
 
      drawarrow(canvas); 
 
      break; 
 
    case status_no_finger: 
 
      // 绘制外圆 
      mpaint.setstyle(style.fill); 
      mpaint.setcolor(mcolornofingeroutter); 
      canvas.drawcircle(mcenterx, mcentery, mradius, mpaint); 
      // 绘制内圆 
      mpaint.setcolor(mcolornofingerinner); 
      canvas.drawcircle(mcenterx, mcentery, mradius 
          * minnercircleradiusrate, mpaint); 
      break; 
 
    } 
 
  } 
 
  /** 
   * 绘制箭头 
   * @param canvas 
   */ 
  private void drawarrow(canvas canvas) 
  { 
    if (marrowdegree != -1) 
    { 
      mpaint.setstyle(paint.style.fill); 
 
      canvas.save(); 
      canvas.rotate(marrowdegree, mcenterx, mcentery); 
      canvas.drawpath(marrowpath, mpaint); 
 
      canvas.restore(); 
    } 
 
  } 
 
  /** 
   * 设置当前模式并重绘界面 
   * 
   * @param mode 
   */ 
  public void setmode(mode mode) 
  { 
    this.mcurrentstatus = mode; 
    invalidate(); 
  } 
 
  public void setarrowdegree(int degree) 
  { 
    this.marrowdegree = degree; 
  } 
 
  public int getarrowdegree() 
  { 
    return this.marrowdegree; 
  } 
} 

注释很详细,主要就是ondraw时,判断当前状态,绘制不同的显示效果;状态的改变都是gesturelockviewgroup的ontouchevent中设置的。

4、gesturelockviewgroup

package com.zhy.zhy_gesturelockview.view; 
 
import java.util.arraylist; 
import java.util.list; 
 
import android.content.context; 
import android.content.res.typedarray; 
import android.graphics.canvas; 
import android.graphics.color; 
import android.graphics.paint; 
import android.graphics.path; 
import android.graphics.point; 
import android.util.attributeset; 
import android.util.log; 
import android.view.motionevent; 
import android.view.view; 
import android.widget.relativelayout; 
 
import com.zhy.zhy_gesturelockview.r; 
import com.zhy.zhy_gesturelockview.view.gesturelockview.mode; 
 
/** 
 * 整体包含n*n个gesturelockview,每个gesturelockview间间隔mmarginbetweenlockview, 
 * 最外层的gesturelockview与容器存在mmarginbetweenlockview的外边距 
 * 
 * 关于gesturelockview的边长(n*n): n * mgesturelockviewwidth + ( n + 1 ) * 
 * mmarginbetweenlockview = mwidth ; 得:mgesturelockviewwidth = 4 * mwidth / ( 5 
 * * mcount + 1 ) 注:mmarginbetweenlockview = mgesturelockviewwidth * 0.25 ; 
 * 
 * @author zhy 
 * 
 */ 
public class gesturelockviewgroup extends relativelayout 
{ 
 
  private static final string tag = "gesturelockviewgroup"; 
  /** 
   * 保存所有的gesturelockview 
   */ 
  private gesturelockview[] mgesturelockviews; 
  /** 
   * 每个边上的gesturelockview的个数 
   */ 
  private int mcount = 4; 
  /** 
   * 存储答案 
   */ 
  private int[] manswer = { 0, 1, 2, 5, 8 }; 
  /** 
   * 保存用户选中的gesturelockview的id 
   */ 
  private list<integer> mchoose = new arraylist<integer>(); 
 
  private paint mpaint; 
  /** 
   * 每个gesturelockview中间的间距 设置为:mgesturelockviewwidth * 25% 
   */ 
  private int mmarginbetweenlockview = 30; 
  /** 
   * gesturelockview的边长 4 * mwidth / ( 5 * mcount + 1 ) 
   */ 
  private int mgesturelockviewwidth; 
 
  /** 
   * gesturelockview无手指触摸的状态下内圆的颜色 
   */ 
  private int mnofingerinnercirclecolor = 0xff939090; 
  /** 
   * gesturelockview无手指触摸的状态下外圆的颜色 
   */ 
  private int mnofingeroutercirclecolor = 0xffe0dbdb; 
  /** 
   * gesturelockview手指触摸的状态下内圆和外圆的颜色 
   */ 
  private int mfingeroncolor = 0xff378fc9; 
  /** 
   * gesturelockview手指抬起的状态下内圆和外圆的颜色 
   */ 
  private int mfingerupcolor = 0xffff0000; 
 
  /** 
   * 宽度 
   */ 
  private int mwidth; 
  /** 
   * 高度 
   */ 
  private int mheight; 
 
  private path mpath; 
  /** 
   * 指引线的开始位置x 
   */ 
  private int mlastpathx; 
  /** 
   * 指引线的开始位置y 
   */ 
  private int mlastpathy; 
  /** 
   * 指引下的结束位置 
   */ 
  private point mtmptarget = new point(); 
 
  /** 
   * 最大尝试次数 
   */ 
  private int mtrytimes = 4; 
  /** 
   * 回调接口 
   */ 
  private ongesturelockviewlistener mongesturelockviewlistener; 
 
  public gesturelockviewgroup(context context, attributeset attrs) 
  { 
    this(context, attrs, 0); 
  } 
 
  public gesturelockviewgroup(context context, attributeset attrs, 
      int defstyle) 
  { 
    super(context, attrs, defstyle); 
    /** 
     * 获得所有自定义的参数的值 
     */ 
    typedarray a = context.gettheme().obtainstyledattributes(attrs, 
        r.styleable.gesturelockviewgroup, defstyle, 0); 
    int n = a.getindexcount(); 
 
    for (int i = 0; i < n; i++) 
    { 
      int attr = a.getindex(i); 
      switch (attr) 
      { 
      case r.styleable.gesturelockviewgroup_color_no_finger_inner_circle: 
        mnofingerinnercirclecolor = a.getcolor(attr, 
            mnofingerinnercirclecolor); 
        break; 
      case r.styleable.gesturelockviewgroup_color_no_finger_outer_circle: 
        mnofingeroutercirclecolor = a.getcolor(attr, 
            mnofingeroutercirclecolor); 
        break; 
      case r.styleable.gesturelockviewgroup_color_finger_on: 
        mfingeroncolor = a.getcolor(attr, mfingeroncolor); 
        break; 
      case r.styleable.gesturelockviewgroup_color_finger_up: 
        mfingerupcolor = a.getcolor(attr, mfingerupcolor); 
        break; 
      case r.styleable.gesturelockviewgroup_count: 
        mcount = a.getint(attr, 3); 
        break; 
      case r.styleable.gesturelockviewgroup_trytimes: 
        mtrytimes = a.getint(attr, 5); 
      default: 
        break; 
      } 
    } 
 
    a.recycle(); 
 
    // 初始化画笔 
    mpaint = new paint(paint.anti_alias_flag); 
    mpaint.setstyle(paint.style.stroke); 
    // mpaint.setstrokewidth(20); 
    mpaint.setstrokecap(paint.cap.round); 
    mpaint.setstrokejoin(paint.join.round); 
    // mpaint.setcolor(color.parsecolor("#aaffffff")); 
    mpath = new path(); 
  } 
 
  @override 
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) 
  { 
    super.onmeasure(widthmeasurespec, heightmeasurespec); 
 
    mwidth = measurespec.getsize(widthmeasurespec); 
    mheight = measurespec.getsize(heightmeasurespec); 
 
    // log.e(tag, mwidth + ""); 
    // log.e(tag, mheight + ""); 
 
    mheight = mwidth = mwidth < mheight ? mwidth : mheight; 
 
    // setmeasureddimension(mwidth, mheight); 
 
    // 初始化mgesturelockviews 
    if (mgesturelockviews == null) 
    { 
      mgesturelockviews = new gesturelockview[mcount * mcount]; 
      // 计算每个gesturelockview的宽度 
      mgesturelockviewwidth = (int) (4 * mwidth * 1.0f / (5 * mcount + 1)); 
      //计算每个gesturelockview的间距 
      mmarginbetweenlockview = (int) (mgesturelockviewwidth * 0.25); 
      // 设置画笔的宽度为gesturelockview的内圆直径稍微小点(不喜欢的话,随便设) 
      mpaint.setstrokewidth(mgesturelockviewwidth * 0.29f); 
 
      for (int i = 0; i < mgesturelockviews.length; i++) 
      { 
        //初始化每个gesturelockview 
        mgesturelockviews[i] = new gesturelockview(getcontext(), 
            mnofingerinnercirclecolor, mnofingeroutercirclecolor, 
            mfingeroncolor, mfingerupcolor); 
        mgesturelockviews[i].setid(i + 1); 
        //设置参数,主要是定位gesturelockview间的位置 
        relativelayout.layoutparams lockerparams = new relativelayout.layoutparams( 
            mgesturelockviewwidth, mgesturelockviewwidth); 
 
        // 不是每行的第一个,则设置位置为前一个的右边 
        if (i % mcount != 0) 
        { 
          lockerparams.addrule(relativelayout.right_of, 
              mgesturelockviews[i - 1].getid()); 
        } 
        // 从第二行开始,设置为上一行同一位置view的下面 
        if (i > mcount - 1) 
        { 
          lockerparams.addrule(relativelayout.below, 
              mgesturelockviews[i - mcount].getid()); 
        } 
        //设置右下左上的边距 
        int rightmargin = mmarginbetweenlockview; 
        int bottommargin = mmarginbetweenlockview; 
        int leftmagin = 0; 
        int topmargin = 0; 
        /** 
         * 每个view都有右外边距和底外边距 第一行的有上外边距 第一列的有左外边距 
         */ 
        if (i >= 0 && i < mcount)// 第一行 
        { 
          topmargin = mmarginbetweenlockview; 
        } 
        if (i % mcount == 0)// 第一列 
        { 
          leftmagin = mmarginbetweenlockview; 
        } 
 
        lockerparams.setmargins(leftmagin, topmargin, rightmargin, 
            bottommargin); 
        mgesturelockviews[i].setmode(mode.status_no_finger); 
        addview(mgesturelockviews[i], lockerparams); 
      } 
 
      log.e(tag, "mwidth = " + mwidth + " , mgestureviewwidth = " 
          + mgesturelockviewwidth + " , mmarginbetweenlockview = " 
          + mmarginbetweenlockview); 
 
    } 
  } 
 
  @override 
  public boolean ontouchevent(motionevent event) 
  { 
    int action = event.getaction(); 
    int x = (int) event.getx(); 
    int y = (int) event.gety(); 
 
    switch (action) 
    { 
    case motionevent.action_down: 
      // 重置 
      reset(); 
      break; 
    case motionevent.action_move: 
      mpaint.setcolor(mfingeroncolor); 
      mpaint.setalpha(50); 
      gesturelockview child = getchildidbypos(x, y); 
      if (child != null) 
      { 
        int cid = child.getid(); 
        if (!mchoose.contains(cid)) 
        { 
          mchoose.add(cid); 
          child.setmode(mode.status_finger_on); 
          if (mongesturelockviewlistener != null) 
            mongesturelockviewlistener.onblockselected(cid); 
          // 设置指引线的起点 
          mlastpathx = child.getleft() / 2 + child.getright() / 2; 
          mlastpathy = child.gettop() / 2 + child.getbottom() / 2; 
 
          if (mchoose.size() == 1)// 当前添加为第一个 
          { 
            mpath.moveto(mlastpathx, mlastpathy); 
          } else 
          // 非第一个,将两者使用线连上 
          { 
            mpath.lineto(mlastpathx, mlastpathy); 
          } 
 
        } 
      } 
      // 指引线的终点 
      mtmptarget.x = x; 
      mtmptarget.y = y; 
      break; 
    case motionevent.action_up: 
 
      mpaint.setcolor(mfingerupcolor); 
      mpaint.setalpha(50); 
      this.mtrytimes--; 
 
      // 回调是否成功 
      if (mongesturelockviewlistener != null && mchoose.size() > 0) 
      { 
        mongesturelockviewlistener.ongestureevent(checkanswer()); 
        if (this.mtrytimes == 0) 
        { 
          mongesturelockviewlistener.onunmatchedexceedboundary(); 
        } 
      } 
 
      log.e(tag, "munmatchexceedboundary = " + mtrytimes); 
      log.e(tag, "mchoose = " + mchoose); 
      // 将终点设置位置为起点,即取消指引线 
      mtmptarget.x = mlastpathx; 
      mtmptarget.y = mlastpathy; 
 
      // 改变子元素的状态为up 
      changeitemmode(); 
       
      // 计算每个元素中箭头需要旋转的角度 
      for (int i = 0; i + 1 < mchoose.size(); i++) 
      { 
        int childid = mchoose.get(i); 
        int nextchildid = mchoose.get(i + 1); 
 
        gesturelockview startchild = (gesturelockview) findviewbyid(childid); 
        gesturelockview nextchild = (gesturelockview) findviewbyid(nextchildid); 
 
        int dx = nextchild.getleft() - startchild.getleft(); 
        int dy = nextchild.gettop() - startchild.gettop(); 
        // 计算角度 
        int angle = (int) math.todegrees(math.atan2(dy, dx)) + 90; 
        startchild.setarrowdegree(angle); 
      } 
      break; 
 
    } 
    invalidate(); 
    return true; 
  } 
 
  private void changeitemmode() 
  { 
    for (gesturelockview gesturelockview : mgesturelockviews) 
    { 
      if (mchoose.contains(gesturelockview.getid())) 
      { 
        gesturelockview.setmode(mode.status_finger_up); 
      } 
    } 
  } 
 
  /** 
   * 
   * 做一些必要的重置 
   */ 
  private void reset() 
  { 
    mchoose.clear(); 
    mpath.reset(); 
    for (gesturelockview gesturelockview : mgesturelockviews) 
    { 
      gesturelockview.setmode(mode.status_no_finger); 
      gesturelockview.setarrowdegree(-1); 
    } 
  } 
  /** 
   * 检查用户绘制的手势是否正确 
   * @return 
   */ 
  private boolean checkanswer() 
  { 
    if (manswer.length != mchoose.size()) 
      return false; 
 
    for (int i = 0; i < manswer.length; i++) 
    { 
      if (manswer[i] != mchoose.get(i)) 
        return false; 
    } 
 
    return true; 
  } 
   
  /** 
   * 检查当前左边是否在child中 
   * @param child 
   * @param x 
   * @param y 
   * @return 
   */ 
  private boolean checkpositioninchild(view child, int x, int y) 
  { 
 
    //设置了内边距,即x,y必须落入下gesturelockview的内部中间的小区域中,可以通过调整padding使得x,y落入范围不变大,或者不设置padding 
    int padding = (int) (mgesturelockviewwidth * 0.15); 
 
    if (x >= child.getleft() + padding && x <= child.getright() - padding 
        && y >= child.gettop() + padding 
        && y <= child.getbottom() - padding) 
    { 
      return true; 
    } 
    return false; 
  } 
 
  /** 
   * 通过x,y获得落入的gesturelockview 
   * @param x 
   * @param y 
   * @return 
   */ 
  private gesturelockview getchildidbypos(int x, int y) 
  { 
    for (gesturelockview gesturelockview : mgesturelockviews) 
    { 
      if (checkpositioninchild(gesturelockview, x, y)) 
      { 
        return gesturelockview; 
      } 
    } 
 
    return null; 
 
  } 
 
  /** 
   * 设置回调接口 
   * 
   * @param listener 
   */ 
  public void setongesturelockviewlistener(ongesturelockviewlistener listener) 
  { 
    this.mongesturelockviewlistener = listener; 
  } 
 
  /** 
   * 对外公布设置答案的方法 
   * 
   * @param answer 
   */ 
  public void setanswer(int[] answer) 
  { 
    this.manswer = answer; 
  } 
 
  /** 
   * 设置最大实验次数 
   * 
   * @param boundary 
   */ 
  public void setunmatchexceedboundary(int boundary) 
  { 
    this.mtrytimes = boundary; 
  } 
 
  @override 
  public void dispatchdraw(canvas canvas) 
  { 
    super.dispatchdraw(canvas); 
    //绘制gesturelockview间的连线 
    if (mpath != null) 
    { 
      canvas.drawpath(mpath, mpaint); 
    } 
    //绘制指引线 
    if (mchoose.size() > 0) 
    { 
      if (mlastpathx != 0 && mlastpathy != 0) 
        canvas.drawline(mlastpathx, mlastpathy, mtmptarget.x, 
            mtmptarget.y, mpaint); 
    } 
 
  } 
 
  public interface ongesturelockviewlistener 
  { 
    /** 
     * 单独选中元素的id 
     * 
     * @param position 
     */ 
    public void onblockselected(int cid); 
 
    /** 
     * 是否匹配 
     * 
     * @param matched 
     */ 
    public void ongestureevent(boolean matched); 
 
    /** 
     * 超过尝试次数 
     */ 
    public void onunmatchedexceedboundary(); 
  } 
} 

注释极其详细,用极其不过分~主要就是ontouchevent中对用户选择的gesturelockview进行判断,以及改变gesturelockview状态等。

5、布局文件

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" 
  xmlns:tools="http://schemas.android.com/tools" 
  xmlns:zhy="http://schemas.android.com/apk/res/com.zhy.zhy_gesturelockview" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" > 
 
  <com.zhy.zhy_gesturelockview.view.gesturelockviewgroup 
    android:id="@+id/id_gesturelockviewgroup" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#f2f2f7" 
    android:gravity="center_vertical" 
    zhy:count="3" 
    zhy:trytimes="5" /> 
<!--  zhy:color_no_finger_inner_circle="#ff085d58" 
    zhy:color_no_finger_outer_circle="#ff08f0e0" 
    zhy:color_finger_on="#ff1734bf" --> 
 
</relativelayout> 

有兴趣的可以自定义属性,把注释的代码添进去就行,当然你也可以什么都不设置,单纯设置宽度和高度,我觉得默认效果也是不错的 ~

6、调用

package com.zhy.zhy_gesturelockview; 
 
import android.app.activity; 
import android.os.bundle; 
import android.widget.toast; 
 
import com.zhy.zhy_gesturelockview.view.gesturelockviewgroup; 
import com.zhy.zhy_gesturelockview.view.gesturelockviewgroup.ongesturelockviewlistener; 
 
public class mainactivity extends activity 
{ 
 
  private gesturelockviewgroup mgesturelockviewgroup; 
 
  @override 
  protected void oncreate(bundle savedinstancestate) 
  { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.activity_main); 
 
    mgesturelockviewgroup = (gesturelockviewgroup) findviewbyid(r.id.id_gesturelockviewgroup); 
    mgesturelockviewgroup.setanswer(new int[] { 1, 2, 3, 4,5 }); 
    mgesturelockviewgroup 
        .setongesturelockviewlistener(new ongesturelockviewlistener() 
        { 
 
          @override 
          public void onunmatchedexceedboundary() 
          { 
            toast.maketext(mainactivity.this, "错误5次...", 
                toast.length_short).show(); 
            mgesturelockviewgroup.setunmatchexceedboundary(5); 
          } 
 
          @override 
          public void ongestureevent(boolean matched) 
          { 
            toast.maketext(mainactivity.this, matched+"", 
                toast.length_short).show(); 
          } 
 
          @override 
          public void onblockselected(int cid) 
          { 
          } 
        }); 
  } 
 
} 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网