Android九宫格解锁的实现

来源:互联网 发布:ubuntu ambari 安装 编辑:程序博客网 时间:2024/04/30 15:19

演示效果如下

这里写图片描述

主要代码如下

布局文件如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <com.xuliugen.jiugongge.SudokuView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_world" /></RelativeLayout>

从布局文件中可以看出需要自定义一个View用于绘制九宫格图案:
SudokuView.java

package com.xuliugen.jiugongge;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;import android.widget.Toast;public class SudokuView extends View {    private static final int DEFALUT_CELL_WIDTH = 60; //默认的cell宽度    private static final int DEFALUT_CELL_STROKE_WIDTH = 2;    private static final int DEFALUT_SPACE = DEFALUT_CELL_WIDTH >> 1;    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 int mWidth;    private int mHeight;    private float mCurrentX;    private float mCurrentY;    private boolean mFinish = false;    private StringBuffer mSbSelected = new StringBuffer(20);    /**     * 下边是三个构造方法:每一个构造方法中有一个初始化操作     */    public SudokuView(Context context) {        super(context);        init();    }    public SudokuView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public SudokuView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    /**     * 初始化操作     */    private void init() {        mCellWidth = DensityUtil.dip2px(getContext(), DEFALUT_CELL_WIDTH);        mCellRadius = DensityUtil.dip2px(getContext(), DEFALUT_CELL_WIDTH >> 1);        mCellStrokeWidth = DensityUtil.dip2px(getContext(),                DEFALUT_CELL_STROKE_WIDTH);        mSpace = DensityUtil.dip2px(getContext(), DEFALUT_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 drawCell(Canvas canvas) {        for (int i = 0; i < 9; i++) {            canvas.drawCircle(mCells[i].getCenterX(), mCells[i].getCenterY(),                    mCellRadius, mCells[i].isSelected() ? mPaintSelected                            : mPaintNormal);        }    }    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);        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        mWidth = getRealSize(widthMeasureSpec);        mHeight = getRealSize(heightMeasureSpec);        setMeasuredDimension(mWidth, mWidth);    }    private int getRealSize(int measureSpc) {        int result;        int mode = MeasureSpec.getMode(measureSpc);        int size = MeasureSpec.getSize(measureSpc);        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.UNSPECIFIED) {            result = mCellWidth * 3 + mSpace * 4;        } else {            result = size;        }        return result;    }    @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;            Toast.makeText(getContext(), mSbSelected.toString(),                    Toast.LENGTH_SHORT).show();            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;    }}

MainActivity.java如下:

package com.xuliugen.jiugongge;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.Menu;import android.view.MenuItem;public class MainActivity extends ActionBarActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        int id = item.getItemId();        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }}

另外还需要一个存放圆圈的Javabean

package com.xuliugen.jiugongge;/** * 代表每一个九宫格圆圈的Javabean * @author xuliugenpc */public class Cell {    private float centerX;    private float centerY;    private boolean selected;    public Cell(float x, float y) {        centerX = x;        centerY = y;    }    public float getCenterX() {        return centerX;    }    public void setCenterX(float centerX) {        this.centerX = centerX;    }    public float getCenterY() {        return centerY;    }    public void setCenterY(float centerY) {        this.centerY = centerY;    }    public boolean isSelected() {        return selected;    }    public void setSelected(boolean selected) {        this.selected = selected;    }}

像素转换的工具类:

package com.xuliugen.jiugongge;import android.content.Context;/** * 手机屏幕px转dp和dp转px工具类  * @author xuliugenpc */public class DensityUtil {    private static float scale;    /**     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)     */    public static int dip2px(Context context, float dpValue) {        if (scale == 0) {            scale = context.getResources().getDisplayMetrics().density;        }        return (int) (dpValue * scale + 0.5f);    }    /**     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp     */    public static int px2dip(Context context, float pxValue) {        if (scale == 0) {            scale = context.getResources().getDisplayMetrics().density;        }        return (int) (pxValue / scale + 0.5f);    }}

全部资源都在这里了,不上传项目代码了哦。

5 1
原创粉丝点击