您的位置:首页 > 其它

自用图形解锁分析

2015-08-15 15:27 239 查看
把以前学过没学好的知识在这个demo中好好复习一下。这是我做的一个仿图形解锁。

总的来说分成三部分:

1.点的绘制

2.点的收集

3.线的绘制

效果图如下:



九宫格点的结构,包括x,y 坐标,三个状态量

public static class Point {
    public static int STATE_NORMAL = 0;
    public static int STATE_PRESSED = 1;
    public static int STATE_ERROR = 2;
    public float x, y;
    public int state = 0;

    public Point(float x, float y) {
        this.x = x;
        this.y = y;
    }

}



一、点的绘制

首先我们要令九宫格都始终在屏幕中间,这要求我们要根据Layout的width,height来计算一个偏移量。每个点都与偏移量关联。

private void initPoint() {

    width = getWidth();
    height = getHeight();

    if (width > height) {//横屏
        offsetX = (width - height) / 2;//计算偏移量,使Lock居中放置
        width = height;
    } else {//竖屏
        offsetY = (height - width) / 2;//计算偏移量,使Lock居中放置
        height = width;
    }

    //各个点之间都间隔width/4,所以每个点的下标都是相差width/4
    points[0][0] = new Point(offsetX + width / 4, offsetY + width / 4);
    points[0][1] = new Point(offsetX + width / 4, offsetY + width * 2 / 4);
    points[0][2] = new Point(offsetX + width / 4, offsetY + width * 3 / 4);

    points[1][0] = new Point(offsetX + width * 2 / 4, offsetY + width / 4);
    points[1][1] = new Point(offsetX + width * 2 / 4, offsetY + width * 2 / 4);
    points[1][2] = new Point(offsetX + width * 2 / 4, offsetY + width * 3 / 4);

    points[2][0] = new Point(offsetX + width * 3 / 4, offsetY + width / 4);
    points[2][1] = new Point(offsetX + width * 3 / 4, offsetY + width * 2 / 4);
    points[2][2] = new Point(offsetX + width * 3 / 4, offsetY + width * 3 / 4);

    isInit = true;//表示初始化完成

}



二、点的收集

我们在onTouch事件中进行判断。

public boolean onTouchEvent(MotionEvent event) {

    Point point = null;
    moveNoPoint = false;
    isFinish = false;
    moveX = event.getX();
    moveY = event.getY();
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {//每次按下都是清空集合
            resetPoint();
            point = checkSelectedPoint();
            if (point != null) {
                isSelect = true;//isSelect的作用就是,ACTION_DOWN时候一定要得到一个有效的起始点,手指移动时才会去收集点
            }
        }
        break;
        case MotionEvent.ACTION_MOVE: {
            if (isSelect) {//如上面所说,有了起始点,才能陆续添加点
                point = checkSelectedPoint();
                if (point == null) {
                    moveNoPoint = true;//moveNoPoint是用来判断是否有重复点,
                }
            }
        }
        break;
        case MotionEvent.ACTION_UP: {//抬手后,isFinish为true,isSelect也回到false以便下次连线使用
            isFinish = true;
            isSelect = false;
        }
        break;
    }

    if (!isFinish && isSelect && point != null) {//选中重复检查
        if (crossPoint(point)) {//重复点判断
            moveNoPoint = true;
        } else {//新点
            point.state = Point.STATE_PRESSED;
            pointPressed_list.add(point);
        }
    }

    if (isFinish) {//onTouch动作结束
        if (pointPressed_list.size() == 1) {//绘制不成立
            resetPoint();
        } else if (pointPressed_list.size() < 5 && pointPressed_list.size() > 2) {//绘制错误,就是点的数量不正确
            errorPoint();
        }
        ;
    }
    //刷新
    postInvalidate();

    return true;
}



三、线的绘制

对集合收集到的点进行绘制就好了


private void LineCanvas(Canvas canvas) {
    if (pointPressed_list.size() == 0) {//集合中没点,不做处理

    } else if (pointPressed_list.size() == 1) {//集合中只要1个点,不能连线,直接画线到触摸位置
        if (isSelect == true) {
            paint.setColor(Color.BLUE);
            paint.setStrokeWidth(20);
            Point point = pointPressed_list.get(0);
            canvas.drawLine(point.x, point.y, moveX, moveY, paint);
        }
    } else {//分两种状态下画线,是否完成onTouch事件
        if (!isFinish) {//onTouch还没结束的话,当集合中最后一个点不是第9个点,则集合最后一点连线到触摸位置
            paint.setColor(Color.BLUE);
            paint.setStrokeWidth(20);
            if (pointPressed_list.size() == 1) {
                Point point = pointPressed_list.get(0);
                //取出当前点的X,Y
                canvas.drawLine(point.x, point.y, moveX, moveY, paint);
            } else {//不是最后一个点,两点之间正常连线
                for (int i = 0; i < pointPressed_list.size() - 1; i++) {
                    Point pointPrevious = pointPressed_list.get(i);
                    Point pointNext = pointPressed_list.get(i + 1);
                    lastX = pointNext.x;
                    lastY = pointNext.y;
                    canvas.drawLine(pointPrevious.x, pointPrevious.y, pointNext.x, pointNext.y, paint);
                }
                if (pointPressed_list.size() < 9) {//当然啦,9个点全画了的话,就不用连线触摸点了
                    canvas.drawLine(lastX, lastY, moveX, moveY, paint);
                }
            }
        } else if (isFinish) {//onTouch事件结束后,就重画所有连线,其中再判断下点的状态是否ERROR
            paint.setColor(Color.BLUE);
            paint.setStrokeWidth(20);
            for (int i = 0; i < pointPressed_list.size() - 1; i++) {
                Point pointPrevious = pointPressed_list.get(i);
                Point pointNext = pointPressed_list.get(i + 1);
                if (pointPrevious.state == Point.STATE_ERROR) {
                    paint.setColor(Color.RED);
                }
                canvas.drawLine(pointPrevious.x, pointPrevious.y, pointNext.x, pointNext.y, paint);
            }
        }
    }
}


CSDN代码下载:http://download.csdn.net/detail/u012232131/9010801
GitHub地址:MyLock源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: