美文网首页Android知识Android开发程序员
android开发图案解锁学习记录二(九宫格间连线时的onTou

android开发图案解锁学习记录二(九宫格间连线时的onTou

作者: zzj丶 | 来源:发表于2016-11-17 15:15 被阅读405次

    `两点一线 ,首先想要怎么画一条线,画线前解决点的问题,点的情况分为两种:两个点的连接,点根据手势的移动线的长短

          重写ontouchEvent方法
    

    监听手势的移动 按下 松开的 动作,根据不同的动作 处理不同的事件图案

    连线将点放入点的集合

    //存放连线后放入的点
    private List<Point> pointList = new ArrayList<>();

    获取手势的坐标 通过event.getX();event.getY();

     * 重写view的ontouchEvent的方法
     * 监听手势的触摸状态
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //获取手势的坐标
        eventX = event.getX();
        eventY = event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN://按下的状态
    
                break;
            case MotionEvent.ACTION_MOVE://移动状态
    
                break;
            case MotionEvent.ACTION_UP://松开后的状态
    
                break;
        }
    
        return true;
    }
    
    

    在自定义的点的类中,添加方法判断手势是否和图案重合(isCoincide()

    /**
     * 判断连线和图案是否重合
     * @param pointX 参考点的x坐标
     * @param pointY 参考点的y坐标
     * @param bitmapR 图案的半径
     * @param eventX 手势的x坐标
     * @param eventY 手势的y坐标
     * @return 是否在图案的范围内
     */
    public boolean isCoincide(float pointX,float pointY,float bitmapR,float eventX,float eventY){
        return Math.sqrt((pointX-eventX)*(pointX-eventX)+(pointY-eventY)*(pointY-eventY))<bitmapR;
    }
    

    通过连线获取屏幕上的点

    当手势处于按下的状态,将点返回;

     /**
         * 当连接线点击了图案后将点返回
         * @return
         */
        private Point checkSelectPoint(){
    
            for(int i = 0;i<points.length;i++){
                for(int j = 0;j<points[i].length;j++){
                    Point point = points[i][j];
    //                手势是否滑到了图案的范围内
                    if(point.isCoincide(point.x,point.y,bitmapR,eventX,eventY)){
                        return point;
                    }
                }
            }
            return null;
        }
    

    判断手势按下去的地方是否是九宫格之内,如果在范围外是不可以出现连线的

    如果我们的选择在范围内,说明我们开始绘制连线了
    Boolean isSelectPoint;

    /**
     * 重写view的ontouchEvent的方法
     * 监听手势的触摸状态
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //获取手势的坐标
        eventX = event.getX();
        eventY = event.getY();
    
        Point point = null;
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN://按下的状态
                //每次按下清空点的集合
                resetPoint();
                point = checkSelectPoint();
                if(point !=null){//如果此点不为null,通过标记设置它为选中状态
                    isSelectPoint = true;
    
                }
                break;
            case MotionEvent.ACTION_MOVE://移动状态
                //判断手势移动到的点是否重复选中
                if(isSelectPoint){
                    point = checkSelectPoint();
                }
                break;
            case MotionEvent.ACTION_UP://松开后的状态
                //当手指抬起,判断绘制是否完成
                isFinsh = true;
                isSelectPoint = false;
    
                break;
    
    
        }
        //判断选中的点是否重复选择
        if(!isFinsh&&isSelectPoint&&point!=null){
    
        }
        //如果绘制完成,判断绘制选中点的结果
        if(isFinsh){
            if(pointList.size()==1){
                //如果只选中一个点,条件不成立,将集合清空
                resetPoint();
            }else if(pointList.size()>1&&pointList.size()<5){
                //绘制错误的状态,图案太简单
                errorPoint();
            }else if(pointList.size()>=5){
    
            }
        }
        //每次刷新view
        postInvalidate();
        return true;
    }
    
    
    /**
     * 条件不成立清空集合
     */
    public void resetPoint(){
        pointList.clear();
    }
    
    /**
     * 绘制错误的方法
     */
    public void errorPoint(){
        //遍历点的集合,将选中的点设置成错误的图案
        for(Point point : pointList){
            point.state = Point.STATE_ERROR;
        }
    }
    
    

    交叉点的判断,当我们选择时进行判断

    /**
     * 交叉点的判断
     * @param point 滑动到的点
     * @return
     */
    private boolean crossPoint(Point point){
        if(pointList.contains(point)){
            //如果集合中包含此点,返回true 否着返回flase
            return true;
        }else {
            return false;
        }
    }
    

    //判断选中的点是否重复选择

            if (!isFinsh && isSelectPoint && point != null) {
    
                if (crossPoint(point)) {
                    //如果重复,不添加到集合中,但绘制并没有结束,添加标记,此标记在重复选择时为true,在九宫格范围外为true
                    moveNoPint = true;
                } else {
    //                如果是新点,将新点的状态设置为按下状态,添加进集合,
                    point.state = Point.STATE_PRESSED;
                    pointList.add(point);
    
                }
            }
    
    

    接下来回到onDraw方法,进行画线

    @Override
    protected void onDraw(Canvas canvas) {
        if (!isInit) {
            initPoints();//初始化图案的点
        }
        canvasPoints(canvas);//绘制点到画布
        //绘制九宫格内的点的连线
        if(pointList.size()>0){
            Point a = pointList.get(0);
            for(int i = 0;i<pointList.size();i++){
                Point b = pointList.get(i);
                lineCanvas(canvas,a,b);
                a = b;
            }
            //如果连线时,手势超出了九宫格的范围,线还是要继续画的
            if(moveNoPint){
               lineCanvas(canvas,a,new Point(eventX,eventY));
            }
        }
    }
    /**
     * 画线
     * @param canvas 画布
     * 画线需要两点一线,
     * @param a 点a
     * @param b 点 b
     */
    private void lineCanvas(Canvas canvas,Point a,Point b){
        //计算线的长度
        float lineLenght = (float) Point.distance(a,b);
        if(a.state == Point.STATE_PRESSED){
            //缩放的比例
            matrix.setScale(lineLenght/linePressed.getWidth(),1);
            //设置矩阵偏移量
            matrix.postTranslate(a.x-linePressed.getWidth()/2,a.y-linePressed.getHeight()/2);
            //画线
            canvas.drawBitmap(linePressed,matrix,paint);
        }else {
            //缩放的比例
            matrix.setScale(lineLenght/lineError.getWidth(),1);
            //设置矩阵偏移量
            matrix.postTranslate(a.x-lineError.getWidth()/2,a.y-lineError.getHeight()/2);
            //画线
            canvas.drawBitmap(lineError,matrix,paint);
        }
    }
    

    在自定义点的类中的计算两点间距离的方法

    /**
     * 两点间的距离
     * @param a 点 a
     * @param b 点 b
     * @return 距离
     */
    public static double distance(Point a,Point b){
        return Math.sqrt(Math.abs(a.x-b.x)*Math.abs(a.x-b.x)+Math.abs(a.y-b.y)*Math.abs(a.y-b.y));
    }```    
    注意:
            如果绘制的线有问题,可能是线的图片的问题,后续我会贴出源码
    未完待续···
    
    有关文章:
    android开发图案解锁学习记录一(九宫格的绘制):http://www.jianshu.com/p/47c731df655a
    android开发图案解锁学习记录三(设置图案监听):http://www.jianshu.com/p/7ab2a8dea3b1
    图案锁源码:https://github.com/z1060932884/LockDemo.git

    相关文章

      网友评论

        本文标题:android开发图案解锁学习记录二(九宫格间连线时的onTou

        本文链接:https://www.haomeiwen.com/subject/leydpttx.html