android -- 做个记录,以后方便回顾

来源:互联网 发布:人工智能主题的基金 编辑:程序博客网 时间:2024/04/27 21:26

--------------------------------效果图。

大致思路:先画出9个圆环,根据手势(down,move,up)重新绘制canvas。比如down的时候设置cell的bitmap为另一张红色圈的图片,move的时候画出一条从currentCell到手指停住的坐标点的直线。up的时候获取手势结果。


注意:①9个环id编号的形式为(1,2,3      当手指down在1号位置,然后move到3号位置时,需要连接1-2,2-3,而不是直接连接1-3。

            4,5,6

           7,8,9)

②辅助线的意思是指,手指移到其他空白区域是的一条辅助线,因为只有手指触摸到圆环内部范围,才能真正的连上一条直线,所以手指触摸在其他非圆环位置的画,画条辅助线,并不保存这条线。

注释应该很详细了 


public class LockPattern extends View{

private Cell cell[] = new Cell[9]; 
private Cell currentCell;
private Paint mPaint; //定义画笔
private int path[][]; //线
private int pathCount;//线的数量

private float mPathx,mPathy;//辅助线,不保存的线。

private int width; 
private int height;
private float screenWidth; //手机屏幕宽度 和 高度
private float screenHeight;

private Bitmap bStart; //不按 显示一个环
private Bitmap bEnd; //按住  显示一个圈

private int bRadius; //环半径

class Cell{
int id; //9个环的编号
Bitmap bitmap; //当前图片
int touched; //触摸编号(单位递增)
float x;//显示位置
float y;
}


public LockPattern(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
mPaint = new Paint();
resetPath();   //初始化边

WindowManager wm = (WindowManager) getContext()
.getSystemService(Context.WINDOW_SERVICE);


screenWidth = wm.getDefaultDisplay().getWidth();
screenHeight = wm.getDefaultDisplay().getHeight();

bStart = BitmapFactory.decodeResource(this.getResources()
, R.drawable.circle_red_start);
bEnd = BitmapFactory.decodeResource(this.getResources()
, R.drawable.circle_red_end);

Log.d("屏幕的宽度和高度", "("+screenWidth+","+screenHeight+")");

initCell(); //初始化9个环
}

public void initCell(){

float bitmapWidth = bStart.getWidth(); //图片宽度
bRadius = (int)(bitmapWidth/2);
float distance = (screenWidth - 3*bitmapWidth)/4; //手势锁 间距
float H = (screenHeight-distance*2-bitmapWidth*3)/2; //锁的上半部分空白高度

for(int i=0;i<3;i++){
for(int k=0;k<3;k++){
int index = i*3+k;
cell[index] = new Cell();
cell[index].id = i*3+k+1;
cell[index].bitmap = bStart;
cell[index].x = distance*(k+1)+bitmapWidth*k;
cell[index].y = H+distance*i+bitmapWidth*i;
cell[index].touched = 0;
}
}
//cell[0].drawable_first = new Drawable();
}




@Override
public void layout(int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.layout(l, t, r, b);
}


@Override
public void draw(Canvas canvas) {
// TODO Auto-generated method stub
super.draw(canvas);
/*mPaint.setColor(Color.GREEN);
mPaint.setStyle(Style.FILL_AND_STROKE);
canvas.drawRect(50, 50, 150, 150, mPaint);
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Style.STROKE);
mPaint.setTextSize(30.0f);
canvas.drawText("computer", 100, 100, mPaint);

mPaint.setStyle(Style.FILL_AND_STROKE);
canvas.drawCircle(200, 200, 50, mPaint);*/

//画环
for(int i=0;i<9;i++){
canvas.drawBitmap(cell[i].bitmap, cell[i].x, cell[i].y, null);
if(cell[i].touched != 0){
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Style.FILL);
}else{
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Style.STROKE);
}
canvas.drawCircle(cell[i].x+bRadius, cell[i].y+bRadius, 10, mPaint);
}
//画线
for(int i=0;i<9;i++){
for(int k=0;k<9;k++){
//Log.d("path["+i+"]["+k+"]",path[i][k]+","+path[k][i]);
if(path[i][k] != 0 && path[k][i] != 0){
mPaint.setStyle(Style.FILL);
mPaint.setStrokeWidth(16);
mPaint.setColor(Color.WHITE);
mPaint.setAlpha(50);
canvas.drawLine(cell[i].x+bRadius, cell[i].y+bRadius
, cell[k].x+bRadius, cell[k].y+bRadius, mPaint);
}
}
}
//画辅助线
if(mPathx!=0 && mPathy!=0){
mPaint.setStyle(Style.FILL);
mPaint.setStrokeWidth(16);
mPaint.setColor(Color.WHITE);
canvas.drawLine(currentCell.x+bRadius, currentCell.y+bRadius
, mPathx, mPathy, mPaint);
}
}


@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
float x = event.getX();
float y = event.getY();
int pCellId = getTouchDownCircle(x, y);

if(event.getAction() == MotionEvent.ACTION_DOWN){
Log.d("MotinEvent","DOWN");
if(pCellId == 0){
return false;
}else{
resetCells(); 
resetPath();
Log.d("press cell id", ""+pCellId);
cell[pCellId-1].bitmap = bEnd;
cell[pCellId-1].touched = 1;
currentCell = cell[pCellId-1];
}
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
//Log.d("MotinEvent", "MOVE");
if(pCellId == 0){
//移动的位置不在下一个环上,所以只画辅助线,不保存
mPathx = x;
mPathy = y;
}else{
//Log.d("move to cell", ""+pCellId);
//Log.d("");
if(cell[pCellId-1].touched == 0){ //判断环是否被点击过
mPathx = 0;
mPathy = 0;

addLines(pCellId); //添加线

currentCell = cell[pCellId-1];
//Log.d("currentCell",currentCell.id+"");
}else{
mPathx = x;
mPathy = y;
}
}

}else if(event.getAction() == MotionEvent.ACTION_UP){
Log.d("MotinEvent","UP");
mPathx = 0;
mPathy = 0;
int res[] = this.getLockPatternResult();
String sRes="";
for(int i=0;i<9;i++)
sRes = sRes+res[i];
Log.d("result",sRes);
}
super.invalidate();
return true;
}


/**
* 重置所有cell
*/
private void resetCells(){
for(int i=0;i<9;i++){
cell[i].bitmap = bStart;
cell[i].touched = 0;
}
}
/**
* 重置path
*/
private void resetPath(){
pathCount = 0;
path = new int[9][9];
for(int i=0;i<9;i++){
for(int k=0;k<9;k++)
path[i][k]=path[k][i] = 0;
}
mPathx = 0;
mPathy = 0;
}
/**
* 判断点击位置点击中哪个环
*/
private int getTouchDownCircle(float x, float y){
for(int i=0;i<9;i++){
//计算两点间的距离
double dis = Math.sqrt((x-cell[i].x-bRadius)*(x-cell[i].x-bRadius)
+ (y-cell[i].y-bRadius)*(y-cell[i].y-bRadius));
if((dis-bRadius)<0){
return cell[i].id;
}
}
return 0;
}

/**
* 添加线(如果1环和3环连接  由于2环处于1,3环之间  则先连接1-2再连接 2-3)
*/
private void addLines(int nextCircle){
int midId; 
if((currentCell.id+nextCircle)%2 == 1){ //判断有无中间环
pathCount++;
path[currentCell.id-1][nextCircle-1] = pathCount; 
path[nextCircle-1][currentCell.id-1] = pathCount;
}else{
midId = (currentCell.id+nextCircle)/2;
float midX = (currentCell.x+cell[nextCircle-1].x)/2;
float midY = (currentCell.y+cell[nextCircle-1].y)/2;
Log.d("midY", "="+midY);
Log.d("cell[mid].y", "="+cell[midId].y);
if(midX == cell[midId-1].x || midY == cell[midId-1].y){ //判断中间环是否符合要求

pathCount++;
path[currentCell.id-1][midId-1] = pathCount; 
path[midId-1][currentCell.id-1] = pathCount; 

cell[midId-1].touched = currentCell.touched+1;//被触摸
cell[midId-1].bitmap = bEnd;//触摸后显示的图片
currentCell = cell[midId-1];

pathCount++;
path[midId-1][nextCircle-1] = pathCount;
path[nextCircle-1][midId-1] = pathCount;
}else{  //不符合要求
pathCount++;
path[currentCell.id-1][nextCircle-1] = pathCount; 
path[nextCircle-1][currentCell.id-1] = pathCount;
}
}
cell[nextCircle-1].touched = currentCell.touched+1;//被触摸
cell[nextCircle-1].bitmap = bEnd;//触摸后显示的图片
}

/**
* 返回手势密码
* @return 
*/
public int[] getLockPatternResult(){
int res[] = new int[9];
for(int i=0;i<9;i++)
res[i] = 0;
for(int i=0;i<9;i++){
if(cell[i].touched > 0)
res[cell[i].touched-1] = cell[i].id;
}
return res;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}


}

0 0
原创粉丝点击