手勢解鎖——進(jìn)階版

我們在Android開發(fā)第三天的時(shí)候也做了手勢解鎖這樣一個(gè)項(xiàng)目,但由于當(dāng)時(shí)還沒學(xué)習(xí)畫板
對點(diǎn)與點(diǎn)之間的線的處理是通過圖片來處理的任洞,所以今天這個(gè)項(xiàng)目運(yùn)用到畫板來代替圖片枚抵,也相當(dāng)于手勢解鎖的一個(gè)進(jìn)階版吧蹬耘,話不多說直接上吧3饧尽欺嗤!

手勢解鎖

activity_main.xml:選擇RelativeLayout方式進(jìn)行布局参萄,另外圖片的布局都由MainActivity代碼完成,所以此處只添加了一個(gè)背景圖片

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:id="@+id/rl_root"
    >

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/bg"
        android:scaleType="center"
        />


</RelativeLayout>

MainActivity:封裝函數(shù)與RelativeLayout布局

public class MainActivity extends AppCompatActivity {

    RelativeLayout rl;
    ArrayList<ImageView> dotViews;
    DrawView drawView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rl = findViewById(R.id.rl_root);
        dotViews=new ArrayList<>();

        //正常顯示的點(diǎn)
        initNineDot(R.drawable.normal, View.VISIBLE);
        //繪制的視圖
        initDrawView();
        //點(diǎn)亮的點(diǎn)
        initNineDot(R.drawable.selected,View.INVISIBLE);
        //將所有點(diǎn)的數(shù)組傳遞給DrawView
        drawView.setDotViews(dotViews);
    }
    private void initDrawView(){
        //創(chuàng)建視圖
        drawView = new DrawView(this);
        //創(chuàng)建布局容器
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        //添加
        rl.addView(drawView, params);
    }
    //圖片 隱藏 tag
    private void initNineDot(int res,int visible){
        float padding = pixelFromDp(40);

        //計(jì)算兩個(gè)點(diǎn)中心點(diǎn)之間的間距
        Point p = new Point();
        getWindowManager()
                .getDefaultDisplay()
                .getSize(p);

        //獲取圖片
        Bitmap bitmap = BitmapFactory
                .decodeResource(getResources()
                        ,res);
        float space = (p.x - 2 * padding - bitmap.getWidth())/2;

        //確定第一個(gè)點(diǎn)的x和y
        float x = padding;
        float y = p.y/2 - space - bitmap.getHeight();

        int index = 1;
        for (int i = 0; i < 3; i++){
            for (int j = 0; j < 3; j++){
                createDot(res,
                        (int) (x + space*j),
                        (int) (y + space*i),
                        visible);
            }
        }
    }

    private void createDot(int res, int left, int top,int visible) {
        //創(chuàng)建圖片視圖
        ImageView iv = new ImageView(this);
        iv.setBackgroundResource(res);
        iv.setVisibility(visible);

        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.leftMargin = left;
        params.topMargin = top;

        //添加視圖
        rl.addView(iv, params);

        //判斷res對應(yīng)的是seleced還是normal
        if (res == R.drawable.selected) {
            dotViews.add(iv);
        }
    }
    //計(jì)算dp對應(yīng)的像素值
    private float pixelFromDp(int size){
        //獲取屏幕的密度
        return size * getResources()
                .getDisplayMetrics()
                .density;
    }
}

DrawView: 畫板視圖放在normal圖片與select圖片中間煎饼,方便點(diǎn)亮但讹挎,所以將onTouchEvent也放在里面,相互調(diào)用

public class DrawView extends View {
    private ArrayList<ImageView> dotViews;
    private Point startPoint;
    private Point endPoint;
    private Paint mPaint;
    private ArrayList<Path> paths;
    private ArrayList<ImageView> selected;
    public DrawView(Context context) {
        super(context);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(20);
        mPaint.setStyle(Paint.Style.STROKE);
        paths = new ArrayList<>();
        selected = new ArrayList<>();
    }
    public void setDotViews(ArrayList<ImageView> dotViews) {
        this.dotViews = dotViews;
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        ImageView dot;
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                dot = viewContainedPoint(x,y);
                if (dot != null){
                    dot.setVisibility(VISIBLE);
                    selected.add(dot);
                    //設(shè)置起始點(diǎn)
                    startPoint = new Point((int)(dot.getPivotX() + dot.getX()),
                            (int)(dot.getPivotY() + dot.getY()));
                }
                break;
            case MotionEvent.ACTION_MOVE:
                dot = viewContainedPoint(x,y);
                if (dot == null){
                    //劃線
                    endPoint = new Point((int)x,(int)y);
                    //刷新
                    invalidate();
                }else{
                    //判斷是第?個(gè)點(diǎn)還是其他
                    if (startPoint == null){
                        //第?個(gè)點(diǎn)
                        dot.setVisibility(VISIBLE);
                        //設(shè)置起始點(diǎn)
                        startPoint = new Point((int)(dot.getPivotX() + dot.getX()),
                                (int)(dot.getPivotY() + dot.getY()));
                    }else{
                        //點(diǎn)亮點(diǎn)
                        dot.setVisibility(VISIBLE);
                        //在之前和現(xiàn)在的點(diǎn)之間產(chǎn)??個(gè)path
                        Path path = new Path();
                        path.moveTo(startPoint.x,startPoint.y);
                        path.lineTo(dot.getPivotX() + dot.getX(),
                                dot.getPivotY() + dot.getY());
                        paths.add(path);
                        //當(dāng)前這個(gè)這個(gè)點(diǎn)就是起始點(diǎn)
                        //設(shè)置起始點(diǎn)
                        startPoint = new Point((int)(dot.getPivotX() + dot.getX()),
                                (int)(dot.getPivotY() + dot.getY()));
                        endPoint = startPoint;
                        //刷新
                        invalidate();
                    }
                    selected.add(dot);
                }
                break;
            case MotionEvent.ACTION_UP:
                clear();
                break;
        }
        return true;
    }
    private void clear(){
        for (ImageView dot: selected){
            dot.setVisibility(INVISIBLE);
        }
        selected.clear();
        paths.clear();
        startPoint = null;
        endPoint = null;
        invalidate();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        if (paths.size() > 0){
            for (Path path: paths){
                canvas.drawPath(path, mPaint);
            }
        }
        if (startPoint != null && endPoint != null) {
            canvas.drawLine(startPoint.x, startPoint.y,
                    endPoint.x, endPoint.y, mPaint);
        }
    }
    //判斷觸摸點(diǎn)是否在某個(gè)dot??
    private ImageView viewContainedPoint(float x,float y){
        for (ImageView dot: dotViews){
            int[] point = new int[2];
            dot.getLocationOnScreen(point);
            //獲取dot的x和y坐標(biāo)
            //int px = point[0];
            //int py = point[1];
            int px = (int) dot.getX();
            int py = (int) dot.getY();
            if ((x >= px && x <= px + dot.getWidth())
                    &&(y >= py && y <= py +dot.getHeight())){
                return dot;
            }
        }
        return null;
    }
}

努力堅(jiān)持_壕痢筒溃!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沾乘,隨后出現(xiàn)的幾起案子铡羡,更是在濱河造成了極大的恐慌,老刑警劉巖意鲸,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烦周,死亡現(xiàn)場離奇詭異,居然都是意外死亡怎顾,警方通過查閱死者的電腦和手機(jī)读慎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來槐雾,“玉大人夭委,你說我怎么就攤上這事∧记浚” “怎么了株灸?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長擎值。 經(jīng)常有香客問我慌烧,道長,這世上最難降的妖魔是什么鸠儿? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任屹蚊,我火速辦了婚禮厕氨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘汹粤。我一直安慰自己命斧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布嘱兼。 她就那樣靜靜地躺著国葬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪芹壕。 梳的紋絲不亂的頭發(fā)上汇四,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機(jī)與錄音哪雕,去河邊找鬼船殉。 笑死鲫趁,一個(gè)胖子當(dāng)著我的面吹牛斯嚎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挨厚,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼堡僻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了疫剃?” 一聲冷哼從身側(cè)響起钉疫,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎巢价,沒想到半個(gè)月后牲阁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壤躲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年城菊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碉克。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凌唬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出漏麦,到底是詐尸還是另有隱情客税,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布撕贞,位于F島的核電站更耻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏捏膨。R本人自食惡果不足惜酥夭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧熬北,春花似錦疙描、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽巫延。三九已至效五,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炉峰,已是汗流浹背畏妖。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疼阔,地道東北人戒劫。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像婆廊,于是被迫代替她去往敵國和親迅细。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程淘邻,因...
    小菜c閱讀 6,419評論 0 17
  • 介紹自己負(fù)責(zé)的部分茵典,如何實(shí)現(xiàn)的。 自定義view viewGroup activity的啟動(dòng)流程 事件傳遞及滑動(dòng)沖...
    東經(jīng)315度閱讀 1,211評論 1 4
  • 每當(dāng)路過小區(qū)廣場宾舅,看見一撥又一撥排著整齊的隊(duì)形伴著優(yōu)美旋律的男女跳著的廣場舞统阿,每次都會(huì)情不自禁地想起陪伴老爸...
    歐陽渝兒閱讀 81評論 0 1
  • 本來想一篇文章寫完,但是又截圖又分析什么的筹我,如果用一篇文章寫扶平,太長了,估計(jì)都沒耐心看完崎溃,所以分成了幾篇來寫蜻直。這篇主...
    八寶君閱讀 3,756評論 0 1
  • 〈高考——繞不過去的坎〉 高三如約而至,假期開學(xué)的第一個(gè)晚自習(xí)袁串,班主任做了第一場有關(guān)高考的渲染概而,只感覺整個(gè)晚上大腦...
    所謂伊人在水依芳閱讀 217評論 0 3