Android开发Android知识Android技术知识

Android九宫格锁屏

2017-01-05  本文已影响201人  一s独秀

Android 九宫格锁屏(已更新,添加了用户操作记录密码,更加完善,更新的在下面)
此demo的重点就在于九宫点的绘制,与用户操作手势的监听交互

效果图

实现思路1(点的绘制)

此图为绘制九点之前的思路(竖屏状态)
思路图

下面我们先新建一个类 SudokuLockViewextends (继承)View,实现继承的方法

重写onDraw方法,在onDraw方法中首先判断要绘制的九点的位置是否初始化,如果没有则实现九点初始化的方法
  private void initView() {

        /**
         * 屏幕宽高
         */
        int pHigth = metrics.heightPixels;
        int pWidth = metrics.widthPixels;

        /**
         * X,Y的偏移量
         */
        float offsetX;
        float offsetY;
        float space; //小方格边长

        /**
         * 判断横竖屏设置对应的值
         */
        if (pHigth > pWidth){
            offsetX = 0;
            offsetY = (pHigth - pWidth)/2;
            space = pWidth/4;
        }else {
            offsetX = (pWidth - pHigth)/2;
            offsetY = 0;
            space = pHigth/4;
        }

        //以下可以用双层for循环更简便
        /**one lines**/
        myPoint[0][0] = new MyPoint(offsetX+space,offsetY+space);
        myPoint[0][1] = new MyPoint(offsetX+space*2,offsetY+space);
        myPoint[0][2] = new MyPoint(offsetX+space*3,offsetY+space);

        /**two lines**/
        myPoint[1][0] = new MyPoint(offsetX+space,offsetY+space*2);
        myPoint[1][1] = new MyPoint(offsetX+space*2,offsetY+space*2);
        myPoint[1][2] = new MyPoint(offsetX+space*3,offsetY+space*2);

        /**three lines**/
        myPoint[2][0] = new MyPoint(offsetX+space,offsetY+space*3);
        myPoint[2][1] = new MyPoint(offsetX+space*2,offsetY+space*3); 
        myPoint[2][2] = new MyPoint(offsetX+space*3,offsetY+space*3);
  }
初始化点的位置之后就可以开始绘制点了(此处的九点可以通过Paint绘制圆形的图标,也可以直接定义一个图片资源,直接将图片资源绘制出来),此处用的第二种方法,同样在初始的方法中添加资源图标的初始
        /**添加点的图片资源**/
        nBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.onetests);
        sBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.twotests);
        eBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.threetests);
之后就可以直接绘制出
  private void drawPoint(Canvas canvas) {
        for (int i = 0;i<myPoint.length;i++){
              for (int j = 0;j<myPoint[i].length;j++){
                  
                  /**
                   * 当然,此处可以判断九点的不同的状态,在绘制(正常的、选中的,错误的)
                   *
                   * @bitR 为图片资源的半径,因为画笔所绘制的不会是从中心电绘制,而是从左上角开始绘制,在这里x,y各减去半径,就会以图标中心的位置开始绘制
                   */
                  canvas.drawBitmap(sBitmap,myPoint[i][j].x-bitR,myPoint[i][j].y-bitR,paint);
               }
        }
  }

好了,现在在XML文件中把我们自定义的这个View添加一下,运行看看,九点的效果就出来了
实现思路2(用户操作)

下面为当用户手指点下并且滑动的时候生成的点,并且返回为选中的九点的任一点,没选中的返回为null
  /**
   * 返回是否选择的是点
   */
  private int[] getSelectPoint() {
        
        //MyPoint自定义的点的类 ,用户手指按下时以x,y生成的点
        MyPoint begainSelectPoint = new MyPoint(moveX,moveY);
        for (int i = 0;i<myPoint.length;i++){
            for (int j = 0;j<myPoint[i].length;j++){
                 //判断距离将选择的点的位置否和一定条件时,为选中
                if (myPoint[i][j].distance(begainSelectPoint) < bitR){

                    //定义长度为2的数组,返回选中点的X,Y
                    int[] result = new int[2];
                    result[0] = i;
                    result[1] = j;
                    return result;
                }
            }
        }
        return null;//选中的不是九点的任一点时
  }
下面上一下onTouchEvent的方法(在此方法中在用户没操作的时候都要显示选中点的状态,所以要及时更新View,可以用this.postInvalidate();方法,及时更新)
  @Override
  public boolean onTouchEvent(MotionEvent event) {
      moveX = event.getX();
      moveY = event.getY();
      switch (event.getAction()){
          case MotionEvent.ACTION_DOWN:
              if (isDrawing){
                  getSelect = getSelectPoint();//用int[]的类型接收
                  if (getSelect != null){
                      x = getSelect[0];//x
                      y = getSelect[1];//y
                      myPoint[x][y].start = MyPoint.SELECT;//设置点的状态
                      allPoint.add(myPoint[x][y]);//添加点到选择点的集合
                  }
              }
              break;
          case MotionEvent.ACTION_MOVE:
              if (isDrawing){
                  getSelect = getSelectPoint();
                  if (getSelect != null){
                      x = getSelect[0];
                      y = getSelect[1];
                      if (!allPoint.contains(myPoint[x][y])){//判断是否已经包含此点
                          myPoint[x][y].start = MyPoint.SELECT;
                          allPoint.add(myPoint[x][y]);
                      }
                  }
              }
              break;
          case MotionEvent.ACTION_UP:
              if (isDrawing){
                  if (allPoint.size() <= 3 && allPoint.size()>0){
                      Toast.makeText(getContext(),"至少不少于四点",Toast.LENGTH_SHORT).show();
                      for (int i = 0;i<allPoint.size();i++){
                          allPoint.get(i).start = MyPoint.ERROR;
                      }
                  }
              }
              if (allPoint.size() > 0){
                  isDrawing = false;
              }
              break;
      }
      this.postInvalidate();//及时更新
      return true;
  }
onTouchEvent方法之后就可以绘制线了,线的绘制是以两点划线,并且,每次讲第二次选择的线赋值为初始点,下面给下选中九点的任一点,和没选中是线的绘制
  private void drawPointLines(Canvas canvas) {
      if (allPoint.size() > 0){
          MyPoint A = allPoint.get(0);
          for (int a = 1;a<allPoint.size();a++){
              MyPoint B = allPoint.get(a);
              drawLines(canvas,A,B);//此为选中九点时的划线的方法
              A = B;
          }
          if (isDrawing){
              drawLines(canvas,A,new MyPoint(moveX,moveY));//当处于绘制状态时,没有选中时,划线就是一手指移动而绘制
          }
      }
  }
绘制线的方法,判断选择的点的个数,绘制不同状态的线
  /**
   * 通过两点绘制线
   * @param canvas
   * @param a
   * @param b
   */
  private void drawLines(Canvas canvas, MyPoint a, MyPoint b) {
      if (a.start == MyPoint.ERROR){
          canvas.drawLine(a.x,a.y,b.x,b.y,epaint);
      }else {
          canvas.drawLine(a.x,a.y,b.x,b.y,paint);
      }
  }
用户操作密码记录

上面的代码我们可以生成一个方法,在用户按下和移动的操作中调用即可

好了,九宫锁到此结束,有更好思路的请告知,以上文章如有错误,请热情指正

上一篇 下一篇

猜你喜欢

热点阅读