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

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


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

二代碼:
(1)這是我們的xml代碼,就是多了一個控件來設(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)槎鄠€函數(shù)都會使用,所以就全局了
    ArrayList<ImageView> dotViews;//關(guān)于ImageView類型的動態(tài)數(shù)組
    mpaint dotpaint;//自定義控件的變量,同樣是因?yàn)槎鄠€地方都會使用

    @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)建九個初始點(diǎn)
        creatmpain();//創(chuàng)建自定義控件
        creatnine(R.drawable.selected,View.INVISIBLE);//注意這里是采用了分層的思想,讓點(diǎn)擊的按鈕對線進(jìn)
        // 行部分覆蓋
        dotpaint.setDotviews(dotViews);//是這9個控件能夠被我們的自定義控件調(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);
        //計算兩個點(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)之間的間隔


        //確定第一個點(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)槲覀儾僮鞯木褪沁@個控件
                    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)用的時候它就會調(diào)用這個函數(shù),所
    // 以要確保這個函數(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ī)時的位置
        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()));
                    //添加,這個點(diǎn)已經(jīng)點(diǎn)過
                    selectedots.add(temp);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                //判斷
                temp = panduan(x,y);
                //不在點(diǎn)控件內(nèi)的時候,記錄終點(diǎn)坐標(biāo)
                if(temp==null){
                endpoint = new Point((int)x,(int)y);
                invalidate();
                }else{
                    if(startpoint==null){
                        //判斷是不是第一個點(diǎn)
                        temp.setVisibility(View.VISIBLE);
                        startpoint=new Point((int)(temp.getPivotX()+temp.getX()),(int)(temp.getPivotY()
                                +temp.getY()));
                    }else{
                        //如果不是第一個點(diǎn)的時候
                        temp.setVisibility(View.VISIBLE);
                        //記錄與上一個點(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);
                        //將這個點(diǎn)設(shè)置為我們的起始點(diǎn)
                        startpoint=new Point((int)(temp.getPivotX()+temp.getX()),(int)(temp.getPivotY()
                                +temp.getY()));
                        //為了美觀,即不在點(diǎn)的控件內(nèi)部滑動時![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();
                    }
                    //這個點(diǎn)已經(jīng)被點(diǎn)擊了
                  selectedots.add(temp);
                }
                break;
            case MotionEvent.ACTION_UP:
                //松手的時候進(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)控件的遍歷,在返回那個點(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容