您好,登錄后才能下訂單哦!
怎么在Android 應(yīng)用中實現(xiàn)一個九宮格手勢鎖?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
主要的方法是重寫View.onTouchEvent( MotionEvent event ) , 常用的三個操作:ACTION_DOWN 手指觸摸屏幕 ; ACTION_UP 手指離開屏幕;
ACTION_MOVE手指在屏幕滑動。
如果該方法返回true ,表示該事件已經(jīng)被View處理,不再向上層的View或Activity傳遞 ; 如果返回false, 表示事件未處理,繼續(xù)傳遞。
實現(xiàn)代碼如下:
package com.ninegrid; 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; /** * Created by Administrator on 2017/6/24. */ public class SuduView extends View { //定義默認常量 private static final int DEFAULT_CELL_WIDTH = 200 ; private static final int DEFAULT_CELL_STROKE_WIDTH = 10 ; private static final int DEFAULT_SPACE = 100 ; //九宮格數(shù)組 private Cell mCells[] = new Cell[9] ; //直徑 private int mCellWidth; //半徑 private int mCellRadius; //邊框?qū)挾? private int mCellStrokeWidth; //空白部分 private int mSpace ; //定義畫筆 private Paint mPaintNormal ; private Paint mPaintSelected ; private float mCurrentX ; private float mCurrentY ; //判斷是否結(jié)束的標識 private boolean mFinish = false ; private StringBuffer mSbSelected = new StringBuffer(20); public SuduView(Context context) { super(context); init(); } public SuduView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public SuduView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ //初始化畫筆 mCellWidth = DEFAULT_CELL_WIDTH ; mCellRadius = DEFAULT_CELL_WIDTH >> 1 ; mCellStrokeWidth = DEFAULT_CELL_STROKE_WIDTH ; mSpace = DEFAULT_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 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); } } 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 ); } } //處理點擊事件 @Override public boolean onTouchEvent(MotionEvent event) { switch ( event.getAction()){ case MotionEvent.ACTION_DOWN: //如果手指已經(jīng)松開,則所有格子變?yōu)槌跏紶顟B(tài) 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; //松開則結(jié)束 case MotionEvent.ACTION_UP: mFinish = true ; 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(); } //根據(jù)坐標判斷點擊的哪個格子 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); //如果點擊的位置在某個格子的圓內(nèi) if( distance < mCellRadius ){ result = i ; break; } } //返回該格子的位置 return result ; } }
最后在布局文件中引用該View即可,若想實現(xiàn)更高的定制性,可以仿照上一篇文章重寫View的onMearsure方法并增加自定義屬性。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。