手勢解鎖簡化版(自定義控件版沒有包含密碼)

嗯础钠,這里實(shí)現(xiàn)了手勢密碼的布局恰力,與點(diǎn)擊的實(shí)現(xiàn),因?yàn)槭菦]有密碼的簡化版所以使用的方法比較簡單珍坊。好了牺勾,廢話不多說,現(xiàn)在就來看看我們的代碼與結(jié)果吧(圖片資源我放在代碼下阵漏,有意向的人可以下載試試喲Wっ瘛)
一結(jié)果展示:


QQ圖片20191116203442.jpg
QQ圖片20191116203452.jpg

二代碼:
(1)這是我們的xml代碼,就是多了一個(gè)控件來設(shè)置背景和主控件的id履怯。

<?xml version="1.0" encoding="utf-8"?>
<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"
    >
    <!--設(shè)置背景函數(shù)回还,不然的話我們的點(diǎn)控件看不清楚-->
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bg"
        android:scaleType="fitXY"/>
</RelativeLayout>

(2)這里是我們的主函數(shù)代碼

package ly.pxd.android12fir;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RelativeLayout;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    float padding;//設(shè)置我們控件對于邊緣的間隔(左右)
    RelativeLayout rl;//主控件變量,因?yàn)槎鄠€(gè)函數(shù)都會使用叹洲,所以就全局了
    ArrayList<ImageView> dotViews;//關(guān)于ImageView類型的動態(tài)數(shù)組
    mpaint dotpaint;//自定義控件的變量柠硕,同樣是因?yàn)槎鄠€(gè)地方都會使用

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rl = findViewById(R.id.rl_root);//找到主控件
        dotViews=new ArrayList<>();//分配空間
        creatnine(R.drawable.normal, View.VISIBLE);//使用方法創(chuàng)建九個(gè)初始點(diǎn)
        creatmpain();//創(chuàng)建自定義控件
        creatnine(R.drawable.selected,View.INVISIBLE);//注意這里是采用了分層的思想,讓點(diǎn)擊的按鈕對線進(jìn)
        // 行部分覆蓋
        dotpaint.setDotviews(dotViews);//是這9個(gè)控件能夠被我們的自定義控件調(diào)用
    }
    private float pixelfromdp(int size){
        //屏幕密度
        return  size*getResources().getDisplayMetrics().density;
    }//就是顯示量度的密度
    private void creatnine(int res , int visible ){
        //創(chuàng)建我們的點(diǎn)
        padding = pixelfromdp(20);
        //計(jì)算兩個(gè)點(diǎn)中心點(diǎn)之間的間距
        Point p = new Point();
        //記錄我們點(diǎn)的坐標(biāo)
        getWindowManager()
                .getDefaultDisplay()
                .getSize(p);//得到我們屏幕的大小


        Bitmap bitmap = BitmapFactory
                .decodeResource(getResources(),res);
        //獲取圖片,從而找出圖片寬高
        float space = (p.x - 2 * padding - bitmap.getWidth())/2;
        //間隔蝗柔,點(diǎn)之間的間隔


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

        //使用雙重循環(huán)闻葵,進(jìn)行點(diǎn)的添加
        for (int i = 0; i < 3; i++){
            for (int j = 0; j < 3; j++){
                //創(chuàng)建圖片視圖
                ImageView iv = new ImageView(this);
                iv.setBackgroundResource(res);
                //設(shè)置位置
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams
                        (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                params.leftMargin = (int)(x+space*j);//注意i,j的取值都是0,1癣丧,2所以space是我們點(diǎn)間隔
                //而padding只是我們點(diǎn)與左右邊緣的間隔
                params.topMargin = (int)(y+space*i);
                iv.setVisibility(visible);//設(shè)置可視屬性
                //添加視圖
                rl.addView(iv,params);
                if(res==R.drawable.selected){//如果是點(diǎn)擊之后的按鈕槽畔,我們就添加,因?yàn)槲覀儾僮鞯木褪沁@個(gè)控件
                    dotViews.add(iv);
                }
            }
        }

    }
    private void creatmpain(){
        dotpaint=new mpaint(this);//分配空間
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);//與屏幕寬高相同
        rl.addView(dotpaint,params);//添加
    }
}

(2)這里是我們的自定義控件代碼

package ly.pxd.android12fir;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

import java.util.ArrayList;

public class mpaint extends View {
    //操作點(diǎn)的數(shù)組
    private ArrayList<ImageView> dotviews;
    //點(diǎn)擊了的點(diǎn)集合胁编,我們要進(jìn)行清空
    private ArrayList<ImageView> selectedots;
    //畫了之后路徑的集合
    private ArrayList<Path> paths ;
    //畫的起始點(diǎn)位置
    Point startpoint;
    //終點(diǎn)位置
    Point endpoint;
    //畫筆
    Paint dotpaint;
    public mpaint(Context context) {
        super(context);
        //我直接在這里初始化厢钧,其實(shí)可以構(gòu)建函數(shù),那樣看起來簡單點(diǎn)
        //分配空間
        selectedots=new ArrayList<>();
        paths=new ArrayList<>();
        dotviews=new ArrayList<>();
        //設(shè)置畫筆屬性
        dotpaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        dotpaint.setColor(Color.WHITE);
        dotpaint.setStrokeWidth(20);
        dotpaint.setStyle(Paint.Style.STROKE);
    }
    //得到我們的操作點(diǎn)
    public void setDotviews(ArrayList<ImageView> dotviews) {
        this.dotviews = dotviews;
    }
    //畫函數(shù)嬉橙,因?yàn)樵谖覀兂绦蜻\(yùn)用的時(shí)候它就會調(diào)用這個(gè)函數(shù)早直,所
    // 以要確保這個(gè)函數(shù)不出錯
    @Override
    protected void onDraw(Canvas canvas) {
        if(paths.size()>0) {
            for (Path path : paths) {
                canvas.drawPath(path, dotpaint);
            }
        }
        if(startpoint!=null&&endpoint!=null){
            canvas.drawLine(startpoint.x,startpoint.y,endpoint.x,endpoint.y,dotpaint);
        }
    }
    //觸摸函數(shù)
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //得到我們點(diǎn)擊手機(jī)時(shí)的位置
        float x = event.getX();
        float y = event.getY();
        ImageView temp;
        //使用switch函數(shù)能夠方便我們對于點(diǎn)擊事件的整理
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //調(diào)用函數(shù),判斷是不是在點(diǎn)控件內(nèi)
                temp = panduan(x,y);
                if(temp!=null){
                    //設(shè)置可視化函數(shù)
                    temp.setVisibility(View.VISIBLE);
                    //記錄位置
                    startpoint=new Point((int)(temp.getPivotX()+temp.getX()),(int)(temp.getPivotY()
                    +temp.getY()));
                    //添加市框,這個(gè)點(diǎn)已經(jīng)點(diǎn)過
                    selectedots.add(temp);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                //判斷
                temp = panduan(x,y);
                //不在點(diǎn)控件內(nèi)的時(shí)候霞扬,記錄終點(diǎn)坐標(biāo)
                if(temp==null){
                endpoint = new Point((int)x,(int)y);
                invalidate();
                }else{
                    if(startpoint==null){
                        //判斷是不是第一個(gè)點(diǎn)
                        temp.setVisibility(View.VISIBLE);
                        startpoint=new Point((int)(temp.getPivotX()+temp.getX()),(int)(temp.getPivotY()
                                +temp.getY()));
                    }else{
                        //如果不是第一個(gè)點(diǎn)的時(shí)候
                        temp.setVisibility(View.VISIBLE);
                        //記錄與上一個(gè)點(diǎn)的路徑
                        Path path = new Path();
                        path.moveTo(startpoint.x,startpoint.y);
                        path.lineTo((temp.getPivotX()+temp.getX()),(temp.getPivotY()
                                +temp.getY()));
                        //添加到我們的動態(tài)數(shù)組
                        paths.add(path);
                        //將這個(gè)點(diǎn)設(shè)置為我們的起始點(diǎn)
                        startpoint=new Point((int)(temp.getPivotX()+temp.getX()),(int)(temp.getPivotY()
                                +temp.getY()));
                        //為了美觀,即不在點(diǎn)的控件內(nèi)部滑動時(shí)![3C2E261C17A51AC1D171A263C1B07407.jpg](https://upload-images.jianshu.io/upload_images/18961721-67c054fe6e130222.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
顯示線
                        endpoint=startpoint;
                        //調(diào)用onDraw函數(shù)
                        invalidate();
                    }
                    //這個(gè)點(diǎn)已經(jīng)被點(diǎn)擊了
                  selectedots.add(temp);
                }
                break;
            case MotionEvent.ACTION_UP:
                //松手的時(shí)候進(jìn)行刷新
                cleardots();
                break;
        }
        return true;
    }
    //刷新函數(shù)
    private void cleardots(){
        for(ImageView temp:selectedots){
            temp.setVisibility(INVISIBLE);
        }
        //清空我們的數(shù)組
        selectedots.clear();
        paths.clear();
        //起始點(diǎn)與終點(diǎn)都設(shè)置為空
        startpoint=null;
        endpoint=null;
    }
    //判斷函數(shù)拾给,判斷點(diǎn)擊的是不是在點(diǎn)控件內(nèi)
    private ImageView panduan(float x , float y ){
        //使用for循環(huán)進(jìn)行點(diǎn)控件的遍歷祥得,在返回那個(gè)點(diǎn)控件兔沃,不在返回空
        for(ImageView temp : dotviews){
            float locax=temp.getX();
            float locay=temp.getY();
            if((x>=locax&&x<=locax+temp.getWidth())&&(y>=locay&&y<=locay+temp.getHeight())){
                return temp;
            }
        }
        return null;
    }
}

三這是我這些代碼用到的圖片文件:
圖片放在這里喲:


C{C3G%O7E9U$ZV{L$ET}KEV.png

資源:
(1)背景


bg.png

(2)未點(diǎn)擊按鈕(是白色的蒋得,所以看不到)


normal.png

(3)已點(diǎn)擊按鈕


selected.png

四,誠然乒疏,懶惰了额衙,不想談什么外部的原因,因?yàn)閯e人都能做到而自己卻做不到怕吴,這也只能是自己的原因了窍侧。不過還好,現(xiàn)在努力雖然有些晚转绷,但也不是沒有救伟件。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市议经,隨后出現(xiàn)的幾起案子斧账,更是在濱河造成了極大的恐慌,老刑警劉巖煞肾,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咧织,死亡現(xiàn)場離奇詭異,居然都是意外死亡籍救,警方通過查閱死者的電腦和手機(jī)习绢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝙昙,“玉大人闪萄,你說我怎么就攤上這事梧却。” “怎么了败去?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵篮幢,是天一觀的道長。 經(jīng)常有香客問我为迈,道長三椿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任葫辐,我火速辦了婚禮搜锰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耿战。我一直安慰自己蛋叼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布剂陡。 她就那樣靜靜地躺著狈涮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸭栖。 梳的紋絲不亂的頭發(fā)上歌馍,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機(jī)與錄音晕鹊,去河邊找鬼松却。 笑死,一個(gè)胖子當(dāng)著我的面吹牛溅话,可吹牛的內(nèi)容都是我干的晓锻。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼飞几,長吁一口氣:“原來是場噩夢啊……” “哼砚哆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屑墨,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤躁锁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后绪钥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灿里,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年程腹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匣吊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖色鸳,靈堂內(nèi)的尸體忽然破棺而出社痛,到底是詐尸還是另有隱情,我是刑警寧澤命雀,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布蒜哀,位于F島的核電站,受9級特大地震影響吏砂,放射性物質(zhì)發(fā)生泄漏撵儿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一狐血、第九天 我趴在偏房一處隱蔽的房頂上張望淀歇。 院中可真熱鬧,春花似錦匈织、人聲如沸浪默。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纳决。三九已至,卻和暖如春乡小,著一層夾襖步出監(jiān)牢的瞬間阔加,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工劲件, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掸哑,地道東北人约急。 一個(gè)月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓零远,卻偏偏與公主長得像,于是被迫代替她去往敵國和親厌蔽。 傳聞我的和親對象是個(gè)殘疾皇子牵辣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

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

  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 6,373評論 0 17
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,093評論 1 32
  • 語文考試 今天下午發(fā)了一張語文試卷奴饮。 剛一發(fā)下來纬向,我一看課外閱讀,...
    張宇劍_閱讀 121評論 0 0
  • 冬天的這個(gè)城市戴卜,窗外的天空有些灰蒙逾条,太陽透不下來,也沒那么陰沉投剥。 外面的天空就像自己的心情师脂,沒有什么事要難過,也快...
    漂若浮塵閱讀 93評論 1 2
  • 一早6點(diǎn)多起床,7點(diǎn)多出發(fā)去阿壩州一臥龍?zhí)葑訙贤讲娇囱┚俺跃M滿期待的一天糕篇。 第一次坐這么早的地鐵。我被成都早7點(diǎn)的...
    私想主義閱讀 373評論 1 4