天天看點

android 手勢解鎖 手勢識别 實作原理 思路分析 100行代碼實作

 1.定義點對象

public class Dot implements Serializable {

    //坐标
    private float x;
    private float y;

    //目前狀态,是否選中
    private boolean isSelected;

    //唯一辨別 用于拼接成數字密碼串 友善儲存和校驗密碼是否正确
    private int index;

    //...get set 方法
}
           

 2.自定義手勢控件

public class LockView extends View {
    private List<Dot> mDotList = new ArrayList<>();//用于存儲1-9圓對于圓心對象 同時用于繪制9個圓
    private List<Dot> mCheckedList = new ArrayList<>();//用于順序記錄手指經過的圓 同時依次拼接每個Dot的index可得數字密碼串
    private int mDotCount = 3;

    private void init(){
        for (int i = 0; i < mDotCount * mDotCount; i++) {           
            float x = xxxx;
            float y = xxxx;
            //初始化點坐标
            mDotList.add(new Dot(x, y, i));
         }
    }
   
}
           

3. 圖形繪制

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        //繪圓
        for (int i = 0; i < mDotList.size(); i++) {
            Dot dot = mDotList.get(i);           
            mPaint.setColor(dot.isSelected() ? mDotSelectedColor : mDotUnSelectedColor);            
            canvas.drawCircle(dot.getX(), dot.getY(), mCircleRadius, mPaint);
        }

        //繪連接配接線
        for (int i = 0; i < mCheckedList.size()-1; i++) {
            Dot dot1 = mDotList.get(i); 
            Dot dot2 = mDotList.get(i+1);        
                        
            canvas.drawLine(dot1.getX(), dot1.getY(), dot2.getX(), dot2.getY(), mPaint);
        }
    }
           

4.事件監聽

@Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mTouchable) {
            int action = event.getAction();
            int x = (int) event.getX();
            int y = (int) event.getY();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    //...
                    break;
                case MotionEvent.ACTION_MOVE:
                    //...
                    // 循環判斷mDotList 是否包含x,y
                    // 包含則mCheckedList.add()
                    for (Dot e: mDotList) {
                        if(Math.hypot(x - e.getX(),y -e.getY())<10){
                            e.setSelected(true);
                            mCheckedList.add(e);
                            break;
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    //...
                    break;
            }
            invalidate();
            return true;
        } else {
            return false;
        }
    }
           

 5.計算密碼

protected String getPassword() {
        StringBuffer sb = new StringBuffer();
        for (Dot e: mCheckedList) {
            sb.append(e.getIndex());
        }
        return sb.toString();
    }
           
android 手勢解鎖 手勢識别 實作原理 思路分析 100行代碼實作