Android 自定義九宮格手勢(shì)鎖
預(yù)覽效果圖如下:
主要的方法是重寫View.onTouchEvent( MotionEvent event ) , 常用的三個(gè)操作:ACTION_DOWN 手指觸摸屏幕 ; ACTION_UP 手指離開屏幕;
ACTION_MOVE手指在屏幕滑動(dòng)。
如果該方法返回true ,表示該事件已經(jīng)被View處理,不再向上層的View或Activity傳遞 ; 如果返回false, 表示事件未處理,繼續(xù)傳遞。
具體代碼如下:
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 { //定義默認(rèn)常量 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é)束的標(biāo)識(shí) 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; //計(jì)算每個(gè)格子的坐標(biāo) 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 ; //繪制每?jī)蓚€(gè)格子中心點(diǎn)之間的連接線 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 ); } } //處理點(diǎn)擊事件 @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 ; } //處理手指移動(dòng)的事件 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ù)坐標(biāo)判斷點(diǎn)擊的哪個(gè)格子 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; } //獲取每個(gè)格子的坐標(biāo) cellX = mCells[i].getCenterX(); cellY = mCells[i].getCenterY(); //計(jì)算按下的點(diǎn)到每個(gè)格子的距離 float tempX = cellX - x ; float tempY = cellY - y ; float distance = (float) Math.sqrt(tempX * tempX + tempY * tempY); //如果點(diǎn)擊的位置在某個(gè)格子的圓內(nèi) if( distance < mCellRadius ){ result = i ; break; } } //返回該格子的位置 return result ; } }
最后在布局文件中引用該View即可,若想實(shí)現(xiàn)更高的定制性,可以仿照上一篇文章重寫View的onMearsure方法并增加自定義屬性。
以上所述是小編給大家介紹的Android 自定義九宮格手勢(shì)鎖,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
實(shí)例講解Android中SQLiteDatabase使用方法
這篇文章主要以一個(gè)簡(jiǎn)單的實(shí)例為大家詳細(xì)講解Android中SQLiteDatabase使用方法,感興趣的小伙伴們可以參考一下2016-05-05Android嵌套滾動(dòng)和協(xié)調(diào)滾動(dòng)的多種實(shí)現(xiàn)方法
嵌套的滾動(dòng)主要方式就是這些,這些簡(jiǎn)單的效果我們用協(xié)調(diào)滾動(dòng),如?CoordinatorLayout?也能實(shí)現(xiàn)同樣的效果,這篇文章主要介紹了Android嵌套滾動(dòng)和協(xié)調(diào)滾動(dòng)的多種實(shí)現(xiàn)方法,需要的朋友可以參考下2022-06-06Android使用TextView,設(shè)置onClick屬性無效的解決方法
下面小編就為大家?guī)硪黄狝ndroid使用TextView,設(shè)置onClick屬性無效的解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12Android實(shí)現(xiàn)ImageView陰影和圖層效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)ImageView陰影和圖層效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02android中在Activity中響應(yīng)ListView內(nèi)部按鈕的點(diǎn)擊事件的兩種方法
本篇文章主要介紹了android中在Activity中響應(yīng)ListView內(nèi)部按鈕的點(diǎn)擊事件的兩種方法,有需要的可以了解一下。2016-11-11Android JNI處理圖片實(shí)現(xiàn)黑白濾鏡的方法
這篇文章主要介紹了Android JNI處理圖片實(shí)現(xiàn)黑白濾鏡的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01Android中BroadcastReceiver(異步接收廣播Intent)的使用
Broadcast Receiver是Android的五大組件之一,使用頻率也很高,用于異步接收廣播Intent,本文將詳細(xì)介紹,需要的朋友可以參考下2012-12-12