>>分享Android开发相关的技术 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 24774 个阅读者 刷新本主题
 * 贴子主题:  Android 自定义九宫格手势锁 回复文章 点赞(0)  收藏  
作者:flybird    发表时间:2020-03-08 16:43:20     消息  查看  搜索  好友  邮件  复制  引用

                                                                                                

Android 自定义九宫格手势锁

                                                                         预览效果图如下:

         点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

主要的方法是重写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方法并增加自定义属性。
                                    
                                                                    
----------------------------
原文链接:https://blog.csdn.net/SakuraMashiro/article/details/73718053

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-03-08 23:07:11 重新编辑]
  Java面向对象编程-->泛型
  JavaWeb开发-->Web运作原理(Ⅲ)
  JSP与Hibernate开发-->Java应用分层架构及软件模型
  Java网络编程-->RMI框架
  精通Spring-->
  Vue3开发-->Vue简介
  通过Https访问的Not trusted Server Certificate的问题的解决...
  Android Broadcast receiver 编程
  android异步更新UI
  Android网络开发-请求队列-性能提升解决方案
  android 手势操作GestureDetector
  Android Service的用法
  Android线程处理简述
  Android定义的路径全局变量
  Android 解码播放GIF图像
  Android多线程断点续传
  Android开发实践:Android.mk模板
  UI渲染机制以及优化
  Android内存优化—dumpsys meminfo详解
  Android性能优化-过度渲染
  Android 之不要滥用 SharedPreferences(下)
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。