android九宫格密码源码,Android九宫格解锁的实现

该博客介绍了如何在Android中自定义一个View组件SudokuView,用于绘制九宫格图案,并处理触摸事件。通过Cell类表示每个单元格,实现了点击选中、连线显示等功能。同时,利用DensityUtil工具类进行尺寸转换,确保在不同设备上适配。
摘要由CSDN通过智能技术生成

主要代码如下

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" >

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/hello_world" />

从布局文件中可以看出需要自定义一个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(),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(),");

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);

}

}

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);

}

}

来自:http://blog.csdn.net/xlgen157387/article/details/46363179

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值