当前位置: 移动技术网 > 移动技术>移动开发>Android > Android 自定义九宫格手势锁

Android 自定义九宫格手势锁

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

 预览效果图如下:

这里写图片描述

主要的方法是重写view.ontouchevent( motionevent event ) , 常用的三个操作:action_down 手指触摸屏幕 ; action_up 手指离开屏幕;

action_move手指在屏幕滑动。

如果该方法返回true ,表示该事件已经被view处理,不再向上层的view或activity传递 ; 如果返回false, 表示事件未处理,继续传递。

具体代码如下:

package com.ninegrid;
import android.content.context;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.util.attributeset;
import android.view.motionevent;
import android.view.view;
/**
 * created by administrator on 2017/6/24.
 */
public class suduview extends view {
  //定义默认常量
  private static final int default_cell_width = 200 ;
  private static final int default_cell_stroke_width = 10 ;
  private static final int default_space = 100 ;
  //九宫格数组
  private cell mcells[] = new cell[9] ;
  //直径
  private int mcellwidth;
  //半径
  private int mcellradius;
  //边框宽度
  private int mcellstrokewidth;
  //空白部分
  private int mspace ;
  //定义画笔
  private paint mpaintnormal ;
  private paint mpaintselected ;
  private float mcurrentx ;
  private float mcurrenty ;
  //判断是否结束的标识
  private boolean mfinish = false ;
  private stringbuffer msbselected = new stringbuffer(20);
  public suduview(context context) {
    super(context);
    init();
  }
  public suduview(context context, attributeset attrs) {
    super(context, attrs);
    init();
  }
  public suduview(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
    init();
  }
  private void init(){
    //初始化画笔
    mcellwidth = default_cell_width ;
    mcellradius = default_cell_width >> 1 ;
    mcellstrokewidth = default_cell_stroke_width ;
    mspace = default_space ;
    mpaintnormal = new paint();
    mpaintnormal.setcolor(color.white);
    mpaintnormal.setstrokewidth(mcellstrokewidth);
    mpaintnormal.setstyle(paint.style.stroke);
    mpaintnormal.setantialias(true);
    mpaintselected = new paint();
    mpaintselected.setcolor(color.cyan);
    mpaintselected.setstrokewidth(mcellstrokewidth);
    mpaintselected.setstyle(paint.style.stroke);
    mpaintselected.setantialias(true);
    cell cell ;
    float x;
    float y;
    //计算每个格子的坐标
    for( int i = 0 ; i < 9 ; i ++ ){
      x = mspace * ( i%3 + 1 ) + mcellradius + mcellwidth * ( i%3 ) ;
      y = mspace * ( i/3 + 1 ) + mcellradius + mcellwidth * ( i/3 ) ;
      cell = new cell(x , y);
      mcells[i] = cell ;
    }
  }
  @override
  protected void ondraw(canvas canvas) {
    super.ondraw(canvas);
    drawcell(canvas);
    drawline(canvas);
  }
  //绘制连接线
  private void drawline( canvas canvas ){
    if("".equals(msbselected.tostring())){
      return;
    }
    string[] selectedindexs = msbselected.tostring().split(",");
    cell cell = mcells[integer.valueof(selectedindexs[0])];
    cell nextcell ;
    //绘制每两个格子中心点之间的连接线
    if( selectedindexs.length > 1) {
      for (int i = 1; i < selectedindexs.length; i++) {
        nextcell = mcells[integer.valueof(selectedindexs[i])];
        canvas.drawline(cell.getcenterx(), cell.getcentery(), nextcell.getcenterx(), nextcell.getcentery(), mpaintselected);
        cell = nextcell;
      }
    }
    //绘制格子到其他空白位置的连接线
    if( !mfinish ) {
      canvas.drawline(cell.getcenterx(), cell.getcentery(), mcurrentx, mcurrenty, mpaintselected);
    }
  }
  private void drawcell( canvas canvas ){
    for ( int i = 0 ; i < 9 ; i ++ ){
      canvas.drawcircle(mcells[i].getcenterx(), mcells[i].getcentery() , mcellradius ,
          mcells[i].isselected() ? mpaintselected : mpaintnormal );
    }
  }
  //处理点击事件
  @override
  public boolean ontouchevent(motionevent event) {
    switch ( event.getaction()){
      case motionevent.action_down:
        //如果手指已经松开,则所有格子变为初始状态
        if( mfinish ){
          for ( int i = 0 ; i < 9 ; i ++ ){
            mcells[i].setselected(false);
          }
          mfinish = false ;
          msbselected.delete(0,msbselected.length());
          invalidate();
          return false;
        }
        handledownevent(event);
        break;
      //松开则结束
      case motionevent.action_up:
        mfinish = true ;
        break;
      case motionevent.action_move:
        handlemoveevent(event);
        break;
    }
    //表示已处理,不向上传递
    return true ;
  }
  //处理手指移动的事件
  private void handlemoveevent( motionevent event ){
    int index = findcellindex(event.getx(),event.gety());
    if( index != -1 ){
      mcells[index].setselected(true);
      msbselected.append(index).append(",");
    }
    invalidate();
    mcurrentx = event.getx();
    mcurrenty = event.gety();
  }
  //处理手指按下的事件
  private void handledownevent( motionevent event){
    int index = findcellindex(event.getx(),event.gety());
    if( index != -1 ){
      mcells[index].setselected(true);
      msbselected.append(index).append(",");
      invalidate();
    }
    mcurrentx = event.getx();
    mcurrenty = event.gety();
  }
  //根据坐标判断点击的哪个格子
  private int findcellindex( float x , float y){
    float cellx ;
    float celly ;
    int result = -1 ;
    for( int i = 0 ; i < 9 ; i ++ ){
      if( mcells[i].isselected()){
        continue;
      }
      //获取每个格子的坐标
      cellx = mcells[i].getcenterx();
      celly = mcells[i].getcentery();
      //计算按下的点到每个格子的距离
      float tempx = cellx - x ;
      float tempy = celly - y ;
      float distance = (float) math.sqrt(tempx * tempx + tempy * tempy);
      //如果点击的位置在某个格子的圆内
      if( distance < mcellradius ){
        result = i ;
        break;
      }
    }
    //返回该格子的位置
    return result ;
  }
}

最后在布局文件中引用该view即可,若想实现更高的定制性,可以仿照上一篇文章重写view的onmearsure方法并增加自定义属性。

以上所述是小编给大家介绍的android 自定义九宫格手势锁,希望对大家有所帮助

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

相关文章:

验证码:
移动技术网