android实现手机密码验证

最近回顾android学习的小项目时,又重新写了一遍android解锁项目,从中回顾了很多知识点,比如界面如何搭建,设置约束,如何获取相册中的图片来更改头像,如何保存密码等等。
效果:


image.png

下面我们开始动手搭建
首先导入我们需要的图片资源


image.png

然后开始对界面进行布局
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.13" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.22" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.3" />

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/icon"
        android:layout_width="80dp"
        android:layout_height="80dp"
        app:civ_border_color="#fff"
        app:civ_border_width="3dp"
        android:src="@mipmap/icon"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/tv_user"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="指尖上的工程師"
        app:layout_constraintBottom_toTopOf="@+id/guideline2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/icon" />

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/guideline3"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline2" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/mContainer"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="50dp"
        android:layout_marginEnd="50dp"
        app:layout_constraintDimensionRatio="w,1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline3">

        <ImageView
            android:id="@+id/rl1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:tag="15"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/hl3"
            app:layout_constraintEnd_toStartOf="@+id/vl2"
            app:layout_constraintStart_toEndOf="@+id/vl1"
            app:layout_constraintTop_toBottomOf="@+id/hl1"
            app:srcCompat="@mipmap/line_right_splash" />

        <ImageView
            android:id="@+id/rl2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:tag="26"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/hl4"
            app:layout_constraintEnd_toStartOf="@+id/vl3"
            app:layout_constraintStart_toEndOf="@+id/vl2"
            app:layout_constraintTop_toBottomOf="@+id/hl2"
            app:srcCompat="@mipmap/line_right_splash" />

        <ImageView
            android:id="@+id/rl3"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:tag="48"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/hl5"
            app:layout_constraintEnd_toStartOf="@+id/vl5"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toEndOf="@+id/vl4"
            app:layout_constraintTop_toBottomOf="@+id/rl1"
            app:srcCompat="@mipmap/line_right_splash" />

        <ImageView
            android:id="@+id/rl4"
            android:layout_width="129dp"
            android:layout_height="111dp"
            android:tag="59"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/hl6"
            app:layout_constraintEnd_toStartOf="@+id/vl6"
            app:layout_constraintStart_toEndOf="@+id/vl5"
            app:layout_constraintTop_toBottomOf="@+id/hl4"
            app:srcCompat="@mipmap/line_right_splash" />

        <ImageView
            android:id="@+id/ll1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:tag="24"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/hl3"
            app:layout_constraintEnd_toStartOf="@+id/vl2"
            app:layout_constraintStart_toEndOf="@+id/vl1"
            app:layout_constraintTop_toBottomOf="@+id/hl1"
            app:srcCompat="@mipmap/line_left_splash" />

        <ImageView
            android:id="@+id/ll2"
            android:layout_width="129dp"
            android:layout_height="109dp"
            android:tag="35"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/hl4"
            app:layout_constraintEnd_toStartOf="@+id/vl3"
            app:layout_constraintStart_toEndOf="@+id/vl2"
            app:layout_constraintTop_toBottomOf="@+id/hl2"
            app:srcCompat="@mipmap/line_left_splash" />

        <ImageView
            android:id="@+id/ll3"
            android:layout_width="129dp"
            android:layout_height="109dp"
            android:tag="57"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/hl5"
            app:layout_constraintEnd_toStartOf="@+id/vl5"
            app:layout_constraintStart_toEndOf="@+id/vl4"
            app:layout_constraintTop_toBottomOf="@+id/hl3"
            app:srcCompat="@mipmap/line_left_splash" />

        <ImageView
            android:id="@+id/ll4"
            android:layout_width="129dp"
            android:layout_height="109dp"
            android:tag="68"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/hl6"
            app:layout_constraintEnd_toStartOf="@+id/vl6"
            app:layout_constraintStart_toEndOf="@+id/vl5"
            app:layout_constraintTop_toBottomOf="@+id/hl4"
            app:srcCompat="@mipmap/line_left_splash" />

        <ImageView
            android:id="@+id/hl1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:scaleX="2"
            android:tag="12"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/vl1"
            app:layout_constraintEnd_toStartOf="@+id/dot2"
            app:layout_constraintStart_toEndOf="@+id/dot1"
            app:layout_constraintTop_toTopOf="@+id/dot1"
            app:srcCompat="@mipmap/line_land" />

        <ImageView
            android:id="@+id/hl2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:scaleX="2"
            android:tag="23"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot2"
            app:layout_constraintEnd_toStartOf="@+id/dot3"
            app:layout_constraintStart_toEndOf="@+id/dot2"
            app:layout_constraintTop_toTopOf="@+id/dot2"
            app:srcCompat="@mipmap/line_land" />

        <ImageView
            android:id="@+id/hl3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:scaleX="2"
            android:tag="45"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot4"
            app:layout_constraintEnd_toStartOf="@+id/dot5"
            app:layout_constraintStart_toEndOf="@+id/dot4"
            app:layout_constraintTop_toTopOf="@+id/dot4"
            app:srcCompat="@mipmap/line_land" />

        <ImageView
            android:id="@+id/hl4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:scaleX="2"
            android:tag="56"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot5"
            app:layout_constraintEnd_toStartOf="@+id/dot6"
            app:layout_constraintStart_toEndOf="@+id/dot5"
            app:layout_constraintTop_toTopOf="@+id/dot5"
            app:srcCompat="@mipmap/line_land" />

        <ImageView
            android:id="@+id/hl5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:scaleX="2"
            android:tag="78"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot7"
            app:layout_constraintEnd_toStartOf="@+id/dot8"
            app:layout_constraintStart_toEndOf="@+id/dot7"
            app:layout_constraintTop_toTopOf="@+id/dot7"
            app:srcCompat="@mipmap/line_land" />

        <ImageView
            android:id="@+id/hl6"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:scaleX="2"
            android:tag="89"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot8"
            app:layout_constraintEnd_toStartOf="@+id/dot9"
            app:layout_constraintStart_toEndOf="@+id/dot8"
            app:layout_constraintTop_toTopOf="@+id/dot8"
            app:srcCompat="@mipmap/line_land" />

        <ImageView
            android:id="@+id/vl1"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:scaleY="2"
            android:tag="14"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/dot4"
            app:layout_constraintEnd_toEndOf="@+id/dot1"
            app:layout_constraintStart_toStartOf="@+id/dot1"
            app:layout_constraintTop_toBottomOf="@+id/dot1"
            app:srcCompat="@mipmap/line_potrot" />

        <ImageView
            android:id="@+id/vl2"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:scaleY="2"
            android:tag="25"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/dot5"
            app:layout_constraintEnd_toEndOf="@+id/dot2"
            app:layout_constraintStart_toStartOf="@+id/dot2"
            app:layout_constraintTop_toBottomOf="@+id/dot2"
            app:srcCompat="@mipmap/line_potrot" />

        <ImageView
            android:id="@+id/vl3"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:scaleY="2"
            android:tag="36"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/dot6"
            app:layout_constraintEnd_toEndOf="@+id/dot3"
            app:layout_constraintStart_toEndOf="@+id/hl2"
            app:layout_constraintTop_toBottomOf="@+id/dot3"
            app:srcCompat="@mipmap/line_potrot" />

        <ImageView
            android:id="@+id/vl4"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:scaleY="2"
            android:tag="47"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/dot7"
            app:layout_constraintEnd_toEndOf="@+id/dot4"
            app:layout_constraintStart_toStartOf="@+id/dot4"
            app:layout_constraintTop_toBottomOf="@+id/sDot4"
            app:srcCompat="@mipmap/line_potrot" />

        <ImageView
            android:id="@+id/vl5"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:scaleY="2"
            android:tag="58"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/dot8"
            app:layout_constraintEnd_toEndOf="@+id/dot5"
            app:layout_constraintStart_toStartOf="@+id/dot5"
            app:layout_constraintTop_toBottomOf="@+id/dot5"
            app:srcCompat="@mipmap/line_potrot" />

        <ImageView
            android:id="@+id/vl6"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:scaleY="2"
            android:tag="69"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@+id/dot9"
            app:layout_constraintEnd_toEndOf="@+id/dot6"
            app:layout_constraintStart_toEndOf="@+id/hl4"
            app:layout_constraintTop_toBottomOf="@+id/dot6"
            app:srcCompat="@mipmap/line_potrot" />

        <ImageView
            android:id="@+id/dot7"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginBottom="20dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/dot8"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintStart_toStartOf="parent"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot7"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="7"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot7"
            app:layout_constraintStart_toStartOf="@+id/dot7"
            app:layout_constraintTop_toTopOf="@+id/dot7"
            app:srcCompat="@mipmap/circle_selected" />

        <ImageView
            android:id="@+id/dot9"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintBottom_toBottomOf="@+id/dot8"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/dot8"
            app:layout_constraintTop_toTopOf="@+id/dot8"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot9"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="9"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot9"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="@+id/dot9"
            app:srcCompat="@mipmap/circle_selected" />

        <ImageView
            android:id="@+id/dot8"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintBottom_toBottomOf="@+id/dot7"
            app:layout_constraintEnd_toStartOf="@+id/dot9"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/dot7"
            app:layout_constraintTop_toTopOf="@+id/dot7"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot8"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="8"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot8"
            app:layout_constraintEnd_toEndOf="@+id/dot8"
            app:layout_constraintTop_toTopOf="@+id/dot8"
            app:srcCompat="@mipmap/circle_selected" />

        <ImageView
            android:id="@+id/dot4"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintBottom_toTopOf="@+id/dot7"
            app:layout_constraintEnd_toStartOf="@+id/dot5"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/dot1"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot4"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="4"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot4"
            app:layout_constraintStart_toStartOf="@+id/dot4"
            app:layout_constraintTop_toTopOf="@+id/dot4"
            app:srcCompat="@mipmap/circle_selected" />

        <ImageView
            android:id="@+id/dot5"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintBottom_toBottomOf="@+id/dot4"
            app:layout_constraintEnd_toStartOf="@+id/dot6"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/dot4"
            app:layout_constraintTop_toTopOf="@+id/dot4"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot5"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="5"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot5"
            app:layout_constraintStart_toStartOf="@+id/dot5"
            app:layout_constraintTop_toTopOf="@+id/dot5"
            app:srcCompat="@mipmap/circle_selected" />

        <ImageView
            android:id="@+id/dot6"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintBottom_toBottomOf="@+id/dot5"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/dot5"
            app:layout_constraintTop_toTopOf="@+id/dot5"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot6"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="6"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot6"
            app:layout_constraintEnd_toEndOf="@+id/dot6"
            app:layout_constraintTop_toTopOf="@+id/dot6"
            app:srcCompat="@mipmap/circle_selected" />

        <ImageView
            android:id="@+id/dot1"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginTop="20dp"
            app:layout_constraintEnd_toStartOf="@+id/dot2"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot1"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="1"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot1"
            app:layout_constraintStart_toStartOf="@+id/dot1"
            app:layout_constraintTop_toTopOf="@+id/dot1"
            app:srcCompat="@mipmap/circle_selected" />

        <ImageView
            android:id="@+id/dot2"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintBottom_toBottomOf="@+id/dot1"
            app:layout_constraintEnd_toStartOf="@+id/dot3"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/dot1"
            app:layout_constraintTop_toTopOf="@+id/dot1"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot2"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="2"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot2"
            app:layout_constraintEnd_toEndOf="@+id/dot2"
            app:layout_constraintStart_toStartOf="@+id/dot2"
            app:layout_constraintTop_toTopOf="@+id/dot2"
            app:srcCompat="@mipmap/circle_selected" />

        <ImageView
            android:id="@+id/dot3"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintBottom_toBottomOf="@+id/dot2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/dot2"
            app:layout_constraintTop_toTopOf="@+id/dot2"
            app:srcCompat="@mipmap/circle_normal" />

        <ImageView
            android:id="@+id/sDot3"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:tag="3"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="@+id/dot3"
            app:layout_constraintEnd_toEndOf="@+id/dot3"
            app:layout_constraintTop_toTopOf="@+id/dot3"
            app:srcCompat="@mipmap/circle_selected" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

大家注意布局的时候要设置好控件对应的大小,如果需要满足布局约束,那便设置为0dp,否则尽量设置为 wrap_content,否则不好设置其他的约束。
然后用数组保存9个圆点的对象,用于滑动过程中进行遍历选中的圆

 /**
     * 懒加载
     * 用数组保存9个圆点的对象,用于滑动过程中进行遍历
     * */
    private val dots by lazy {
        arrayOf(sDot1, sDot2, sDot3, sDot4, sDot5, sDot6, sDot7, sDot8, sDot9)
    }

保存所有的tag值

/**
     * 保存所有的tag值
     * */
    private val mTags = arrayOf(
        12, 23, 45, 56, 78, 89,
        14, 25, 36, 47, 58, 69,
        15, 26, 48, 59, 24, 35, 57, 68
    )

使用懒加载获取标题栏的高度,也就是显示电量那一栏的高度,获取到了,用于点击事件时,判断触摸点的位置坐标

 /**
     * 使用懒加载获取标题栏的高度
     * */
    private val barHeight by lazy {
        //获取屏幕尺寸
        val display = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(display)
        //获取操作区域尺寸
        val drawingRect = Rect()
        window.findViewById<ViewGroup>(Window.ID_ANDROID_CONTENT).getDrawingRect(drawingRect)
        display.heightPixels - drawingRect.height()
    }

获取当前这个触摸点所在的圆点视图

 /**
     * 获取当前这个触摸点所在的圆点视图
     * */
    private fun getCurPoint(point: Point): ImageView? {
        //遍历所有的点 是否包含这个point
        for (dotView in dots) {
            getRectForView(dotView).also {
                if (it.contains(point.x, point.y)) {
                    return dotView
                }
            }
        }
        return null
    }

 //获取视图对应的Rect
    private fun getRectForView(v: ImageView) = Rect(v.left, v.top, v.right, v.bottom)

将触摸点的坐标转化为相对容器的坐标

 /**
     * 将触摸点的坐标转化为相对容器的坐标
     * */
    private fun convertToContainer(event: MotionEvent): Point {
        return Point().apply {
            //x坐标 = 触摸点的x - 容器的x
            x = (event.x - mContainer.x).toInt()
            //y坐标 = 触摸点的y - 状态栏高度 - 容器的y
            y = (event.y - mContainer.y - barHeight).toInt()
        }
    }

保存当前被点亮的视图,密码

/**
     * 保存当前被点亮的视图
     * */
    private val selectedDots = mutableListOf<ImageView>()

    /**
     * 保存当前点亮的上一个点
     * */
    private var lastSelectedView: ImageView? = null

    /**
     * 保存密码
     * */
    private var password = StringBuilder()

判断两次密码是否一致

//判断两次密码是否一致(未设置密码)
    private fun comparePassWord(first: String, second: String) {
        //确认密码
        if (first == second) {
            //两次密码一致
            tv_content.text = "密码设置成功"
            orgPassWord = first
            SharedPreferenceUtil.getInstance(this).savePassWord(first)
        } else {
            tv_content.text = "密码不一致,密码设置失败"
            firstPassWord = null
        }
    }

验证两次密码是否一致(已经设置了密码)

 //验证两次密码是否一致(已经设置了密码)
    private fun verPassWord(first: String, second: String) {
        //确认密码
        if (first == second) {
            //两次密码一致
            tv_content.text = "密码解锁成功"
            SharedPreferenceUtil.getInstance(this).savePassWord(first)
        } else {
            tv_content.text = "输入密码错误"
            firstPassWord = null
        }
    }

当触摸位置正确时点亮这个视图

/**
     * 点亮圆和线
     * */
    private fun highLightView(v: ImageView?) {
        v?.also {
            if (it.visibility == View.INVISIBLE) {
                //如果这个点是第一个点,点亮并保存
                if (lastSelectedView == null) {
                    highLightDot(v)
                } else {
                    //获取线的tag值
                    val previous = (lastSelectedView?.tag as String).toInt()
                    val current = (v.tag as String).toInt()
                    val lineTag =
                        if (previous > current) current * 10 + previous else previous * 10 + current
                    //判断是否有这个条线
                    if (mTags.contains(lineTag)) {
                        //点亮这个点
                        highLightDot(v)
                        //点亮这条线
                        mContainer.findViewWithTag<ImageView>(lineTag.toString()).apply {
                            visibility = View.VISIBLE
                            selectedDots.add(this)
                        }
                    }
                }
            }
        }
    }

这里需要注意点亮线使用的是对应的tag值,小的tag*10+大的tag值就得到对应的tag值,然后判断这条线是否已经点亮,再点亮它。
响应点击事件

 override fun onTouchEvent(event: MotionEvent?): Boolean {

        val point = convertToContainer(event!!)
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                getCurPoint(point).also {
                    highLightView(it)
                }
            }
            MotionEvent.ACTION_MOVE -> {
                getCurPoint(point).also {
                    highLightView(it)

                }
            }
            MotionEvent.ACTION_UP -> {
                //判断是不是第一次设置密码
                if (orgPassWord == null) {
                    if (firstPassWord == null) {
                        firstPassWord = password.toString()
                        tv_content.text = "请确认密码"
                    } else {
                        //确认密码
                        comparePassWord(firstPassWord!!, password.toString())
                    }
                } else {
                    //验证密码
                    verPassWord(orgPassWord!!, password.toString())
                }

                reSet()
            }
        }
        return true
    }

这里注意当手没有滑动的时候,需要判断密码是否正确,这里逻辑稍微复杂了一些,主要是需要判断是设置密码还是验证密码。

还原操作

/**
     * 还原操作
     * */
    private fun reSet() {
        //遍历保存点亮的数组
        for (item in selectedDots) {
            item.visibility = View.INVISIBLE

        }
        //清空
        selectedDots.clear()
        lastSelectedView = null
        Log.v("pxd", password.toString())
        password.clear()
    }

用户切换头像操作

 //切换头像
    private fun changeIcon() {
        icon.setOnClickListener {
            //从相册选择一张图片
            Intent().apply {
                action = Intent.ACTION_PICK
                type = "image/*"
                startActivityForResult(this, REQUEST_IMAGE_CODE)
            }
        }
    }

点击头像后获取相册

    //自定义请求类型
    private val REQUEST_IMAGE_CODE = 123
    private val REQUEST_VIDEO_CODE = 124

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            REQUEST_IMAGE_CODE -> {
                //图片
                //判断用户是否取消操作
                if (resultCode != Activity.RESULT_CANCELED) {
                    //获取图片
                    val uri = data?.data
                    uri?.let {
                        //对IO操作尽量使用use
                        contentResolver.openInputStream(uri).use {
                            BitmapFactory.decodeStream(it).also { image ->
                                //显示图片
                                icon.setImageBitmap(image)
                                //将图片缓存起来
                                val file = File(filesDir, "icon.jpg")
                                FileOutputStream(file).also { fos ->
                                    //将图片缓存到fos对应的路径
                                    image.compress(Bitmap.CompressFormat.JPEG, 50, fos)
                                }
                            }
                        }
                    }
                }
            }
            REQUEST_VIDEO_CODE -> {

            }
        }
    }

这里注意对IO操作尽量使用use,然后获取图片后将图片保存到对应的文件夹

最后是在onCreate方法中调用对应的方法,并显示文本的内容

  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //获取密码
        orgPassWord = SharedPreferenceUtil.getInstance(this).getPassWord().also {
            if (it != null) {
                //确认密码
                tv_content.text = "请解锁图案"
            } else {
                //设置密码
                tv_content.text = "请设置密码"
            }
        }

        changeIcon()
        //获取头像
        File(filesDir, "icon.jpg").also {
            if (it.exists()) {
                BitmapFactory.decodeFile(it.path).also { image ->
                    icon.setImageBitmap(image)
                }
            }
        }

    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,835评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,900评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,481评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,303评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,375评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,729评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,877评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,633评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,088评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,443评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,563评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,251评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,827评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,712评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,943评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,240评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,435评论 2 348

推荐阅读更多精彩内容