您的位置:首页 > 移动开发 > Android开发

Android 图案解锁 9宫格密码解锁

2016-07-17 19:55 771 查看
序言  第一次写Android技术博客,不知道该如何下手。

背景  现在人们越来越重视自己的隐私,对于一些涉及用户隐私的应用,用户可能会希望在应用启动时必须先输入密码。传统的数字式密码记忆繁琐、容易破解,而图案解锁则可以解决这个问题。因此,在应用中添加图案解锁功能,可以提高应用的可靠性,获得用户的信任。 

今天,我要介绍的是Android 的屏幕9宫格图形解锁,如果有什么不对的地方,望各位批评指正。直接上代码

1. 首先自定义图形密码控件,继承自View,创建并绘制9个点,并重写onTouchEvent方法。

public class GestureLock extends View {

    private Point[][] points = new Point[3][3];

    private boolean inited = false;

    private boolean isDraw = false;

    private ArrayList<Point> pointList = new ArrayList<Point>();

    private ArrayList<Integer> passList = new ArrayList<Integer>();

    private Bitmap bitmapPointError;

    private Bitmap bitmapPointNormal;

    private Bitmap bitmapPointPress;

    private OnDrawFinishedListener listener;

    float mouseX, mouseY;

    private float bitmapR;

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    Paint pressPaint = new Paint();

    Paint errorPaint = new Paint();

    public GestureLock(Context context) {

        super(context);

    }

    public GestureLock(Context context, AttributeSet attrs) {

        super(context, attrs);

    }

    public GestureLock(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);

    }

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        mouseX = event.getX();

        mouseY = event.getY();

        int[] ij;

        int i, j;

        switch (event.getAction())

        {

            case MotionEvent.ACTION_DOWN:

                resetPoints();

                ij = getSelectedPoint();

                if (ij != null)

                {

                    isDraw = true;

                    i = ij[0];

                    j = ij[1];

                    points[i][j].state = Point.STATE_PRESS;

                    pointList.add(points[i][j]);

                    passList.add(i * 3 + j);

                }

                break;

            case MotionEvent.ACTION_MOVE:

                if (isDraw)

                {

                    ij = getSelectedPoint();

                    if (ij != null)

                    {

                        i = ij[0];

                        j = ij[1];

                        if(!pointList.contains(points[i][j]))

                        {

                            points[i][j].state = Point.STATE_PRESS;

                            pointList.add(points[i][j]);

                            passList.add(i * 3 + j);

                        }

                    }

                }

                break;

            case MotionEvent.ACTION_UP:

                boolean valid = false;

                if (listener != null && isDraw)

                {

                    valid = listener.OnDrawFinished(passList);

                }

                if (!valid)

                {

                    for (Point p : pointList)

                    {

                        p.state = Point.STATE_ERROR;

                    }

                }

                isDraw = false;

                break;

        }

        this.postInvalidate();

        return true;

    }

    private int[] getSelectedPoint()

    {

        Point pMouse = new Point(mouseX, mouseY);

        for (int i = 0; i < points.length; i++)

        {

            for (int j = 0; j < points[i].length; j++)

            {

                if (points[i][j].distance(pMouse) < bitmapR)

                {

                    int[] result = new int[2];

                    result[0] = i;

                    result[1] = j;

                    return result;

                }

            }

        }

        return null;

    }

    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        if (!inited)

        {

            init();

        }

        drawPoints(canvas);

        if (pointList.size() > 0)

        {

            Point a = pointList.get(0);

            for (int i = 1;i < pointList.size(); i++)

            {

                Point b = pointList.get(i);

                drawLine(canvas, a, b);

                a = b;

            }

            if (isDraw)

            {

                drawLine(canvas, a, new Point(mouseX, mouseY));

            }

        }

    }

    private void drawLine(Canvas canvas, Point a, Point b)

    {

        if (a.state == Point.STATE_PRESS)

        {

            canvas.drawLine(a.x, a.y, b.x, b.y, pressPaint);

        }

        else if(a.state == Point.STATE_ERROR)

        {

            canvas.drawLine(a.x, a.y, b.x, b.y, errorPaint);

        }

    }

    private void drawPoints(Canvas canvas)

    {

        for (int i = 0; i < points.length; i++)

        {

            for (int j = 0; j < points[i].length; j++)

            {

                if (points[i][j].state == Point.STATE_NORMAL)

                {

                    //Normal

                    canvas.drawBitmap(bitmapPointNormal, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);

                }

                else if (points[i][j].state == Point.STATE_PRESS)

                {

                    //Press

                    canvas.drawBitmap(bitmapPointPress, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);

                }

                else {

                    //ERROR

                    canvas.drawBitmap(bitmapPointError, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);

                }

            }

        }

    }

    private void init()

    {

        pressPaint.setColor(Color.YELLOW);

        pressPaint.setStrokeWidth(5);

        errorPaint.setColor(Color.RED);

        errorPaint.setStrokeWidth(5);

        bitmapPointError = BitmapFactory.decodeResource(getResources(), R.mipmap.error);

        bitmapPointNormal = BitmapFactory.decodeResource(getResources(), R.mipmap.normal);

        bitmapPointPress = BitmapFactory.decodeResource(getResources(), R.mipmap.press);

        bitmapR = bitmapPointError.getHeight() / 2;

        int width = getWidth();

        int height = getHeight();

        int offset = Math.abs(width - height) / 2;

        int offsetX, offsetY;

        int space;

        if(width > height)

        {

            space = height / 4;

            offsetX = offset;

            offsetY = 0;

        }

        else

        {

            space = width / 4;

            offsetX = 0;

            offsetY = offset;

        }

        points[0][0] = new Point(offsetX + space, offsetY + space);

        points[0][1] = new Point(offsetX + space * 2, offsetY + space);

        points[0][2] = new Point(offsetX + space * 3, offsetY + space);

        points[1][0] = new Point(offsetX + space, offsetY + space * 2);

        points[1][1] = new Point(offsetX + space * 2, offsetY + space * 2);

        points[1][2] = new Point(offsetX + space * 3, offsetY + space * 2);

        points[2][0] = new Point(offsetX + space, offsetY + space * 3);

        points[2][1] = new Point(offsetX + space * 2, offsetY + space * 3);

        points[2][2] = new Point(offsetX + space * 3, offsetY + space * 3);

        inited = true;

    }

    public void resetPoints()

    {

        passList.clear();

        pointList.clear();

        for (int i = 0; i < points.length; i++)

        {

            for (int j = 0; j < points[i].length; j++)

            {

                points[i][j].state = Point.STATE_NORMAL;

            }

        }

        this.postInvalidate();

    }

    public interface OnDrawFinishedListener

    {

        boolean OnDrawFinished(List<Integer> passList);

    }

    public void setOnDrawFinishedListener(OnDrawFinishedListener listener)

    {

        this.listener = listener;

    }

}

辅助类 Point.java

public class Point {

    public static int STATE_NORMAL = 0;

    public static int STATE_PRESS = 1;

    public static int STATE_ERROR = 2;

    float x;

    float y;

    int state = STATE_NORMAL;

    public Point(float x, float y)

    {

        this.x = x;

        this.y = y;

    }

    public float distance(Point a)

    {

        float distance = (float)Math.sqrt((x - a.x) * (x - a.x) + (y - a.y) * (y - a.y));

        return distance;

    }

}

2.MainActivity.java  设置和检验密码锁。

public class MainActivity extends ActionBarActivity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Button btn_setting = (Button)findViewById(R.id.button);

        Button btn_lock = (Button)findViewById(R.id.button2);

        btn_setting.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                Intent intent = new Intent(MainActivity.this, SettingActivity.class);

                startActivity(intent);

            }

        });

        btn_lock.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                Intent intent = new Intent(MainActivity.this, LockActivity.class);

                startActivity(intent);

            }

        });

    }

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.

        getMenuInflater().inflate(R.menu.menu_main, menu);

        return true;

    }

    @Override

    public boolean onOptionsItemSelected(MenuItem item) {

        // Handle action bar item clicks here. The action bar will

        // automatically handle clicks on the Home/Up button, so long

        // as you specify a parent activity in AndroidManifest.xml.

        int id = item.getItemId();

        //noinspection SimplifiableIfStatement

        if (id == R.id.action_settings) {

            return true;

        }

        return super.onOptionsItemSelected(item);

    }

}

大体核心代码就是这些,后面有demo链接,可根据需要自行下载。

Demo源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息