Android九宮格解鎖的實現

jopen 9年前發布 | 2K 次閱讀 Java Android

主要代碼如下

布局文件如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&quot;
    xmlns:tools="http://schemas.android.com/tools&quot;
    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></pre>
從布局文件中可以看出需要自定義一個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;
}

}</pre>
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);
}

}</pre>

另外還需要一個存放圓圈的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;
    

    } }</pre>

    像素轉換的工具類:

    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); } }</pre>
      來自:http://blog.csdn.net/xlgen157387/article/details/46363179
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!