最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實(shí)現(xiàn)九宮格圖案解鎖

 更新時(shí)間:2022年06月28日 11:20:41   作者:tracydragonlxy  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)九宮格圖案解鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Android實(shí)現(xiàn)九宮格圖案解鎖的具體代碼,供大家參考,具體內(nèi)容如下

前言:自定義了一個(gè)九宮格的VIew來繪制九宮格圖案,實(shí)現(xiàn)了繪制圖案解鎖的功能。

效果圖如下:

1. 第一步

自定義九宮格View。

public class LockPatterView extends View {

? ? private static final int POINT_SIZE = 5;
? ? private Point[][] points = new Point[3][3];
? ? private boolean isInit,isSelect,isFinish,movePoint;
? ? private Matrix matrix = new Matrix();
? ? private float width,height,offstartX,offstartY,moveX,moveY;;
? ? private Bitmap bitmap_pressed,bitmap_normal,bitmap_error,bitmap_line,bitmap_line_error;
? ? private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
? ? private List<Point> pointList = new ArrayList<Point>();
? ? private OnPatterChangeLister onPatterChangeLister;
? ? public LockPatterView(Context context, AttributeSet attrs, int defStyle) {
? ? ? ? super(context, attrs, defStyle);
? ? }

? ? public LockPatterView(Context context, AttributeSet attrs) {
? ? ? ? super(context, attrs);
? ? }

? ? public LockPatterView(Context context) {
? ? ? ? super(context);
? ? }

? ? @Override
? ? protected void onDraw(Canvas canvas) {
? ? ? ? if (!isInit) {
? ? ? ? ? ? initPoints();
? ? ? ? }
? ? ? ? points2Canvas(canvas);

? ? ? ? if (pointList.size() > 0) {
? ? ? ? ? ? Point a = pointList.get(0);
? ? ? ? ? ? for (int i = 0; i < pointList.size(); i++) {
? ? ? ? ? ? ? ? Point b = pointList.get(i);
? ? ? ? ? ? ? ? line2Canvas(canvas, a, b);
? ? ? ? ? ? ? ? a = b;
? ? ? ? ? ? }
? ? ? ? ? ? if (movePoint) {
? ? ? ? ? ? ? ? line2Canvas(canvas, a, new Point(moveX, moveY));
? ? ? ? ? ? }
? ? ? ? }
? ? }

? ? /**
? ? ?* @param canvas
? ? ?*/
? ? private void points2Canvas(Canvas canvas) {
? ? ? ? for (int i = 0; i < points.length; i++) {
? ? ? ? ? ? for (int j = 0; j < points[i].length; j++) {
? ? ? ? ? ? ? ? Point point = points[i][j];
? ? ? ? ? ? ? ? if (point.state == Point.STATE_PRESSED) {
? ? ? ? ? ? ? ? ? ? canvas.drawBitmap(bitmap_pressed, point.x - bitmap_normal.getWidth()/2, point.y - bitmap_normal.getHeight() / 2, paint);
? ? ? ? ? ? ? ? }else if (point.state == Point.STATE_ERROR) {
? ? ? ? ? ? ? ? ? ? canvas.drawBitmap(bitmap_error, point.x - bitmap_normal.getWidth()/2, point.y - bitmap_normal.getHeight() / 2, paint);
? ? ? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? ? ? canvas.drawBitmap(bitmap_normal, point.x - bitmap_normal.getWidth()/2, point.y - bitmap_normal.getHeight() / 2, paint);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }


? ? /**
? ? ?*
? ? ?* @param canvas
? ? ?* @param
? ? ?* @param
? ? ?*/
? ? public void line2Canvas(Canvas canvas,Point a,Point b){
? ? ? ? float linelength = (float) Point.distance(a, b);
? ? ? ? float degress = getDegrees(a,b);
? ? ? ? canvas.rotate(degress, a.x, a.y);

? ? ? ? if (a.state == Point.STATE_PRESSED) {
? ? ? ? ? ? matrix.setScale(linelength / bitmap_line.getWidth(), 1);
? ? ? ? ? ? matrix.postTranslate(a.x, a.y);
? ? ? ? ? ? canvas.drawBitmap(bitmap_line, matrix, paint);
? ? ? ? }else{
? ? ? ? ? ? matrix.setScale(linelength / bitmap_line.getWidth(), 1);
? ? ? ? ? ? matrix.postTranslate(a.x, a.y);
? ? ? ? ? ? canvas.drawBitmap(bitmap_line_error, matrix, paint);
? ? ? ? }
? ? ? ? canvas.rotate(-degress, a.x, a.y);
? ? }

? ? public float getDegrees(Point pointA, Point pointB) {
? ? ? ? return (float) Math.toDegrees(Math.atan2(pointB.y - pointA.y, pointB.x - pointA.x));
? ? }

? ? /**
? ? ?*/
? ? private void initPoints() {

? ? ? ? width = getWidth();
? ? ? ? height = getHeight();

? ? ? ? if (width > height) {
? ? ? ? ? ? offstartX = (width - height) / 2;
? ? ? ? ? ? width = height;
? ? ? ? }else{
? ? ? ? ? ? offstartY = (height - width) / 2;
? ? ? ? ? ? height = width;
? ? ? ? }

? ? ? ? bitmap_normal = BitmapFactory.decodeResource(getResources(), R.mipmap.normal);
? ? ? ? bitmap_pressed = BitmapFactory.decodeResource(getResources(), R.mipmap.press);
? ? ? ? bitmap_error = BitmapFactory.decodeResource(getResources(), R.mipmap.error);
? ? ? ? bitmap_line = BitmapFactory.decodeResource(getResources(), R.mipmap.line_normal);
? ? ? ? bitmap_line_error = BitmapFactory.decodeResource(getResources(), R.mipmap.line_error);

? ? ? ? points[0][0] = new Point(offstartX + width / 4,offstartY + height / 4);
? ? ? ? points[0][1] = new Point(offstartX + width / 2,offstartY + height / 4);
? ? ? ? points[0][2] = new Point(offstartX + width - width / 4,offstartY + height / 4);

? ? ? ? points[1][0] = new Point(offstartX + width / 4,offstartY + width / 2);
? ? ? ? points[1][1] = new Point(offstartX + width / 2,offstartY + width / 2);
? ? ? ? points[1][2] = new Point(offstartX + width - width / 4,offstartY + width / 2);

? ? ? ? points[2][0] = new Point(offstartX + width / 4,offstartY + width - width / 4);
? ? ? ? points[2][1] = new Point(offstartX + width / 2,offstartY + width - width / 4);
? ? ? ? points[2][2] = new Point(offstartX + width - width / 4,offstartY + width - width / 4);

? ? ? ? isInit = true;
? ? }

? ? @Override
? ? public boolean onTouchEvent(MotionEvent event) {
? ? ? ? moveX = event.getX();
? ? ? ? moveY = event.getY();
? ? ? ? movePoint = false;
? ? ? ? isFinish = false;

? ? ? ? Point point = null;

? ? ? ? switch (event.getAction()) {
? ? ? ? case MotionEvent.ACTION_DOWN:
? ? ? ? ? ? if (onPatterChangeLister != null) {
? ? ? ? ? ? ? ? onPatterChangeLister.onPatterStart(true);
? ? ? ? ? ? }
? ? ? ? ? ? resetPoint();

? ? ? ? ? ? point = chechSelectPoint();
? ? ? ? ? ? if (point != null) {
? ? ? ? ? ? ? ? isSelect = true;
? ? ? ? ? ? }
? ? ? ? ? ? break;
? ? ? ? case MotionEvent.ACTION_MOVE:
? ? ? ? ? ? if (isSelect) {
? ? ? ? ? ? ? ? point = chechSelectPoint();
? ? ? ? ? ? ? ? if (point == null) {
? ? ? ? ? ? ? ? ? ? movePoint = true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? break;
? ? ? ? case MotionEvent.ACTION_UP:
? ? ? ? ? ? isFinish = true;
? ? ? ? ? ? isSelect = false;
? ? ? ? ? ? break;

? ? ? ? }
? ? ? ? if (!isFinish && isSelect && point != null) {
? ? ? ? ? ? if (crossPoint(point)) {
? ? ? ? ? ? ? ? movePoint = true;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? point.state = Point.STATE_PRESSED;
? ? ? ? ? ? ? ? pointList.add(point);
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? if (isFinish) {
? ? ? ? ? ? if (pointList.size() == 1) {
? ? ? ? ? ? ? ? errorPoint();
? ? ? ? ? ? }else if(pointList.size() < POINT_SIZE && pointList.size() > 0 ){
? ? ? ? ? ? ? ? ?errorPoint();
? ? ? ? ? ? ? ? ?if (onPatterChangeLister != null) {
? ? ? ? ? ? ? ? ? ? ? ? onPatterChangeLister.onPatterChange(null);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? if (onPatterChangeLister != null) {
? ? ? ? ? ? ? ? ? ? String pass = "";
? ? ? ? ? ? ? ? ? ? for (int i = 0; i < pointList.size(); i++) {
? ? ? ? ? ? ? ? ? ? ? ? pass = pass + pointList.get(i).index;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (!TextUtils.isEmpty(pass)) {
? ? ? ? ? ? ? ? ? ? ? ? onPatterChangeLister.onPatterChange(pass);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? postInvalidate();
? ? ? ? return true;
? ? }

? ? /**
? ? ?* @param point
? ? ?* @return
? ? ?*/
? ? private boolean crossPoint(Point point){
? ? ? ? if (pointList.contains(point)) {
? ? ? ? ? ? return true;
? ? ? ? }else{
? ? ? ? ? ? return false;
? ? ? ? }
? ? }

? ? /**
? ? ?*/
? ? public void resetPoint(){
? ? ? ? for (int i = 0; i < pointList.size(); i++) {
? ? ? ? ? ? Point point = pointList.get(i);
? ? ? ? ? ? point.state = Point.STATE_NORMAL;
? ? ? ? }
? ? ? ? pointList.clear();
? ? }

? ? /**
? ? ?*/
? ? public void errorPoint(){
? ? ? ? for (Point point : pointList) {
? ? ? ? ? ? point.state = Point.STATE_ERROR;
? ? ? ? }
? ? }

? ? /**
? ? ?* @return
? ? ?*/
? ? private Point chechSelectPoint(){
? ? ? ? for (int i = 0; i < points.length; i++) {
? ? ? ? ? ? for (int j = 0; j < points[i].length; j++) {
? ? ? ? ? ? ? ? Point point = points[i][j];
? ? ? ? ? ? ? ? if (Point.with(point.x, point.y, bitmap_normal.getWidth() / 2, moveX, moveY)) {
? ? ? ? ? ? ? ? ? ? return point;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? return null;
? ? }

? ? public static class Point{
? ? ? ? public static int STATE_NORMAL = 0;
? ? ? ? public static int STATE_PRESSED = 1;
? ? ? ? public static int STATE_ERROR = 2;
? ? ? ? public float x,y;
? ? ? ? public int index = 0,state = 0;
? ? ? ? public Point(){};

? ? ? ? public Point(float x,float y){
? ? ? ? ? ? this.x = x;
? ? ? ? ? ? this.y = y;
? ? ? ? }

? ? ? ? /**
? ? ? ? ?* @param a
? ? ? ? ?* @param b
? ? ? ? ?* @return
? ? ? ? ?*/
? ? ? ? public static double distance(Point a,Point b){
? ? ? ? ? ? return Math.sqrt(Math.abs(a.x - b.x) * Math.abs(a.x - b.x) + Math.abs(a.y - b.y) * Math.abs(a.y - b.y)) ;
? ? ? ? }

? ? ? ? /**
? ? ? ? ?*?
? ? ? ? ?* @param paintX
? ? ? ? ?* @param pointY
? ? ? ? ?* @param r
? ? ? ? ?* @param moveX
? ? ? ? ?* @param moveY
? ? ? ? ?* @return
? ? ? ? ?*/
? ? ? ? public static boolean with(float paintX,float pointY,float r,float moveX,float moveY){
? ? ? ? ? ? return Math.sqrt((paintX - moveX) * (paintX - moveX) + (pointY - moveY) * (pointY - moveY)) < r ;
? ? ? ? }
? ? }

}

2. 第二步

編寫布局文件activity_main.xml,在主布局文件中引入自定義的View。

<?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">

? ? <com.newdegree.mylock.LockPatterView
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="wrap_content"/>

</RelativeLayout>

最后,運(yùn)行程序就能看到九宮格圖案了。

總結(jié):這樣我們就完成了九宮格圖案解鎖的開發(fā),我們可以在自己完成的程序中繪制各種解鎖圖案。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android編程實(shí)現(xiàn)在Activity中操作刷新另外一個(gè)Activity數(shù)據(jù)列表的方法

    Android編程實(shí)現(xiàn)在Activity中操作刷新另外一個(gè)Activity數(shù)據(jù)列表的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)在Activity中操作刷新另外一個(gè)Activity數(shù)據(jù)列表的方法,結(jié)合具體實(shí)例形式分析了2種常用的Activity交互實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06
  • Android 啟動(dòng)模式FLAG_ACTIVITY_CLEAR_TOP案例詳解

    Android 啟動(dòng)模式FLAG_ACTIVITY_CLEAR_TOP案例詳解

    這篇文章主要介紹了Android 啟動(dòng)模式FLAG_ACTIVITY_CLEAR_TOP案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Android ListView在Fragment中的使用示例詳解

    Android ListView在Fragment中的使用示例詳解

    這篇文章主要介紹了Android ListView在Fragment中的使用,因?yàn)楣ぷ饕恢痹谟胢vvm框架,因此這篇文章是基于mvvm框架寫的,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • Flutter改變狀態(tài)變量是否必須寫在setState回調(diào)詳解

    Flutter改變狀態(tài)變量是否必須寫在setState回調(diào)詳解

    這篇文章主要為大家介紹了Flutter改變狀態(tài)變量是否必須寫在setState回調(diào)里的原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 在啟動(dòng)欄制作android studio啟動(dòng)圖標(biāo)

    在啟動(dòng)欄制作android studio啟動(dòng)圖標(biāo)

    這篇文章主要介紹了在啟動(dòng)欄制作android studio啟動(dòng)圖標(biāo)的相關(guān)知識(shí),需要的朋友可以參考下
    2018-03-03
  • 揭秘在ListView等AdapterView上動(dòng)態(tài)添加刪除項(xiàng)的陷阱

    揭秘在ListView等AdapterView上動(dòng)態(tài)添加刪除項(xiàng)的陷阱

    今天遇到這么個(gè)需求,需要在運(yùn)行時(shí)動(dòng)態(tài)添加ListView的item,看起來很簡(jiǎn)單,實(shí)際操作過程中卻遇到了麻煩,下面揭秘在ListView等AdapterView上動(dòng)態(tài)添加刪除項(xiàng)的陷阱
    2016-04-04
  • Android?Retrofit使用詳細(xì)教程

    Android?Retrofit使用詳細(xì)教程

    Retrofit是Android用來接口請(qǐng)求的網(wǎng)絡(luò)框架,內(nèi)部是基于OkHttp實(shí)現(xiàn)的,retrofit負(fù)責(zé)接口請(qǐng)求的封裝,retrofit可以直接將接口數(shù)據(jù)解析為Bean類、List集合等,直接簡(jiǎn)化了中間繁瑣的數(shù)據(jù)解析過程,這篇文章主要介紹了Android?Retrofit使用詳情,需要的朋友可以參考下
    2024-03-03
  • Android使用AndroidUtilCode實(shí)現(xiàn)多語言

    Android使用AndroidUtilCode實(shí)現(xiàn)多語言

    這篇文章主要為大家介紹了Android使用AndroidUtilCode實(shí)現(xiàn)多語言示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Android控件系列之RadioButton與RadioGroup使用方法

    Android控件系列之RadioButton與RadioGroup使用方法

    本文介紹了Android中如何使用RadioGroup和RadioButton,對(duì)比了RadioButton和CheckBox的區(qū)別,并實(shí)現(xiàn)了自定義的RadioGroup中被選中RadioButton的變更監(jiān)聽事件
    2012-11-11
  • Android?高德地圖POI定位地址搜索功能

    Android?高德地圖POI定位地址搜索功能

    這篇文章主要介紹了Android?高德地圖POI定位地址搜索功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-02-02

最新評(píng)論

克什克腾旗| 平度市| 自贡市| 兴隆县| 黔东| 南郑县| 双牌县| 彩票| 神农架林区| 丰城市| 连州市| 左贡县| 油尖旺区| 油尖旺区| 长白| 宿州市| 申扎县| 吉水县| 竹北市| 金门县| 郴州市| 淳安县| 嵊州市| 锡林郭勒盟| 威海市| 东宁县| 高邑县| 福贡县| 惠来县| 南安市| 新绛县| 钟山县| 宜黄县| 青龙| 公安县| 准格尔旗| 西城区| 马尔康县| 始兴县| 尼勒克县| 临朐县|