滑动解锁

完整滑动解锁:

效果:

程序第一次运行起来,

       

在次确定密码 当确认密码一致时则设置成功

     

当不一致时重新绘制:

当已经确定了密码之后在次启动程序则直接输入密码:

更换头像点击头像进入相册选择:

                 

代码地址:https://github.com/luofangli/SlideUnlock

完整代码

app的:

     的   添加:

implementation 'de.hdodenhof:circleimageview:3.1.0'

中:

<?xml version="1.0" encoding="utf-8"?>

<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.2" />

<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.3" />

<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.4" />

<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/headerImage"
android:layout_width="100dp"
android:layout_height="100dp"
app:civ_border_width="2dp"
app:civ_border_color="@color/colorAccent"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/head" />

<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="哎睡的懒洋洋"
android:textAlignment="center"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/guideline2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline" />

<TextView
android:id="@+id/pwdText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="1111"
android:textAlignment="center"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/guideline3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
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_marginTop="48dp"
android:layout_marginEnd="50dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline3">

<ImageView
android:id="@+id/dot1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/dot4"
app:layout_constraintEnd_toStartOf="@+id/dot2"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/circle_normal" />

<ImageView
android:id="@+id/dot2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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="@drawable/circle_normal" />

<ImageView
android:id="@+id/dot3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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="@drawable/circle_normal" />

<ImageView
android:id="@+id/dot4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/dot7"
app:layout_constraintStart_toStartOf="@+id/dot1"
app:layout_constraintTop_toBottomOf="@+id/dot1"
app:srcCompat="@drawable/circle_normal" />

<ImageView
android:id="@+id/dot5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@+id/dot2"
app:layout_constraintTop_toTopOf="@+id/dot4"
app:srcCompat="@drawable/circle_normal" />

<ImageView
android:id="@+id/dot6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@+id/dot3"
app:layout_constraintTop_toTopOf="@+id/dot5"
app:srcCompat="@drawable/circle_normal" />

<ImageView
android:id="@+id/dot7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/dot4"
app:layout_constraintTop_toBottomOf="@+id/dot4"
app:srcCompat="@drawable/circle_normal" />

<ImageView
android:id="@+id/dot8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@+id/dot5"
app:layout_constraintTop_toTopOf="@+id/dot7"
app:srcCompat="@drawable/circle_normal" />

<ImageView
android:id="@+id/dot9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@+id/dot6"
app:layout_constraintTop_toTopOf="@+id/dot8"
app:srcCompat="@drawable/circle_normal" />

<ImageView
android:id="@+id/sdot1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="1"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot1"
app:layout_constraintTop_toTopOf="@+id/dot1"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/sdot2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="2"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot2"
app:layout_constraintTop_toTopOf="@+id/dot2"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/sdot3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="3"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot3"
app:layout_constraintTop_toTopOf="@+id/dot3"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/sdot4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="4"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot4"
app:layout_constraintTop_toTopOf="@+id/dot4"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/sdot5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="5"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot5"
app:layout_constraintTop_toTopOf="@+id/dot5"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/sdot6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="6"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot6"
app:layout_constraintTop_toTopOf="@+id/dot6"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/sdot7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="7"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot7"
app:layout_constraintTop_toTopOf="@+id/dot7"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/sdot8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="8"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot8"
app:layout_constraintTop_toTopOf="@+id/dot8"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/sdot9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="9"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/dot9"
app:layout_constraintTop_toTopOf="@+id/dot9"
app:srcCompat="@drawable/circle_selected" />

<ImageView
android:id="@+id/line1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:tag="12"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/dot1"
app:layout_constraintEnd_toStartOf="@+id/dot2"
app:layout_constraintStart_toEndOf="@+id/dot1"
app:layout_constraintTop_toTopOf="@+id/dot1"
app:srcCompat="@drawable/line_land" />

<ImageView
android:id="@+id/line2"
android:layout_width="42dp"
android:layout_height="wrap_content"
android:tag="23"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/dot3"
app:layout_constraintEnd_toStartOf="@+id/dot3"
app:layout_constraintStart_toEndOf="@+id/dot2"
app:layout_constraintTop_toTopOf="@+id/dot3"
app:srcCompat="@drawable/line_land" />

<ImageView
android:id="@+id/line3"
android:layout_width="42dp"
android:layout_height="wrap_content"
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="@drawable/line_land" />

<ImageView
android:id="@+id/line4"
android:layout_width="42dp"
android:layout_height="wrap_content"
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="@drawable/line_land" />

<ImageView
android:id="@+id/line5"
android:layout_width="42dp"
android:layout_height="wrap_content"
android:tag="78"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/dot8"
app:layout_constraintEnd_toStartOf="@+id/dot8"
app:layout_constraintStart_toEndOf="@+id/dot7"
app:layout_constraintTop_toTopOf="@+id/dot8"
app:srcCompat="@drawable/line_land" />

<ImageView
android:id="@+id/line6"
android:layout_width="42dp"
android:layout_height="wrap_content"
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="@drawable/line_land" />

<ImageView
android:id="@+id/pline1"
android:layout_width="wrap_content"
android:layout_height="0dp"
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="@drawable/line_potrot" />

<ImageView
android:id="@+id/pline2"
android:layout_width="wrap_content"
android:layout_height="42dp"
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="@drawable/line_potrot" />

<ImageView
android:id="@+id/pline3"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:tag="36"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/dot6"
app:layout_constraintEnd_toEndOf="@+id/dot3"
app:layout_constraintStart_toStartOf="@+id/dot3"
app:layout_constraintTop_toBottomOf="@+id/dot3"
app:srcCompat="@drawable/line_potrot" />

<ImageView
android:id="@+id/pline4"
android:layout_width="wrap_content"
android:layout_height="42dp"
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/dot4"
app:srcCompat="@drawable/line_potrot" />

<ImageView
android:id="@+id/pline5"
android:layout_width="wrap_content"
android:layout_height="42dp"
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="@drawable/line_potrot" />

<ImageView
android:id="@+id/pline6"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:tag="69"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/dot9"
app:layout_constraintEnd_toEndOf="@+id/dot6"
app:layout_constraintStart_toStartOf="@+id/dot6"
app:layout_constraintTop_toBottomOf="@+id/dot6"
app:srcCompat="@drawable/line_potrot" />

<ImageView
android:id="@+id/sline1"
android:layout_width="0dp"
android:layout_height="0dp"
android:tag="15"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/line3"
app:layout_constraintEnd_toStartOf="@+id/pline2"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/pline1"
app:layout_constraintTop_toBottomOf="@+id/line1"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/line_right_splash" />

<ImageView
android:id="@+id/sline2"
android:layout_width="0dp"
android:layout_height="0dp"
android:tag="24"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/line3"
app:layout_constraintEnd_toStartOf="@+id/pline2"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/pline1"
app:layout_constraintTop_toBottomOf="@+id/line1"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/line_left_splash" />

<ImageView
android:id="@+id/sline3"
android:layout_width="0dp"
android:layout_height="0dp"
android:tag="26"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/line4"
app:layout_constraintEnd_toStartOf="@+id/pline3"
app:layout_constraintStart_toEndOf="@+id/pline2"
app:layout_constraintTop_toBottomOf="@+id/line2"
app:srcCompat="@drawable/line_right_splash" />

<ImageView
android:id="@+id/sline4"
android:layout_width="0dp"
android:layout_height="0dp"
android:tag="35"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/line4"
app:layout_constraintEnd_toStartOf="@+id/pline3"
app:layout_constraintStart_toEndOf="@+id/pline2"
app:layout_constraintTop_toBottomOf="@+id/line2"
app:srcCompat="@drawable/line_left_splash" />

<ImageView
android:id="@+id/sline5"
android:layout_width="0dp"
android:layout_height="0dp"
android:tag="57"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/line5"
app:layout_constraintEnd_toStartOf="@+id/pline5"
app:layout_constraintStart_toEndOf="@+id/pline4"
app:layout_constraintTop_toBottomOf="@+id/line3"
app:srcCompat="@drawable/line_left_splash" />

<ImageView
android:id="@+id/sline6"
android:layout_width="0dp"
android:layout_height="0dp"
android:tag="48"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/line5"
app:layout_constraintEnd_toStartOf="@+id/pline5"
app:layout_constraintStart_toEndOf="@+id/pline4"
app:layout_constraintTop_toBottomOf="@+id/line3"
app:srcCompat="@drawable/line_right_splash" />

<ImageView
android:id="@+id/sline7"
android:layout_width="0dp"
android:layout_height="0dp"
android:tag="68"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/line6"
app:layout_constraintEnd_toStartOf="@+id/pline6"
app:layout_constraintStart_toEndOf="@+id/pline5"
app:layout_constraintTop_toBottomOf="@+id/line4"
app:srcCompat="@drawable/line_left_splash" />

<ImageView
android:id="@+id/sline8"
android:layout_width="0dp"
android:layout_height="0dp"
android:tag="59"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/line6"
app:layout_constraintEnd_toStartOf="@+id/pline6"
app:layout_constraintStart_toEndOf="@+id/pline5"
app:layout_constraintTop_toBottomOf="@+id/line4"
app:srcCompat="@drawable/line_right_splash" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

该类中:

package com.example.my_2

import android.content.Context

class SharePrefrenceUtil private constructor(){
private val FILE_NAME = "password"
private val KEY = "passwordkey"
companion object{
//为了保证整个程序的运行过程中只能SharePerenceUtil,
/*要调用sharedpreference就必须要用context,而该类中没有继承activity,
是没有context的,所以要在该类中使用sharedpreference就通过instence传递过来的
context给mcontext继而能够调用sharedpreference

*/
private var mcontext:Context? = null
private var instance:SharePrefrenceUtil ? = null
fun getInstance(context: Context) :SharePrefrenceUtil {
mcontext = context
if (instance == null){
synchronized(this){
instance = SharePrefrenceUtil()
}
}
return instance !!
}
}
fun savePassword(pwd:String){
/*
sharedpreference是生成一个xml文件用于管理存进去的数据
FILE_NAME:xml文件的名字
Context.MODE_PRIVATE:是管理文件的模式,这里是指这个文件是私有的,只能本应用程序调用,
外部程序是无法调用的
*/
//获取sharedpreference对象
val sharedPreferences = mcontext?.getSharedPreferences(FILE_NAME,Context.MODE_PRIVATE)
//获取edit-》是用于写入数据
val sharededit = sharedPreferences?.edit()
//写入数据
sharededit?.putString(KEY,pwd)
sharededit?.apply()
}
fun getPassword():String?{
//获取sharedpreference
val sharedPreferences = mcontext?.getSharedPreferences(FILE_NAME,Context.MODE_PRIVATE)
//获取数据
return sharedPreferences?.getString(KEY,null)
}
fun clearpassword(){
//获取sharedpreference
val sharedPreferences = mcontext?.getSharedPreferences(FILE_NAME,Context.MODE_PRIVATE)
sharedPreferences?.edit()?.clear()?.apply()
}
}

该类中:

package com.example.my_2

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Point
import android.graphics.Rect
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.io.FileOutputStream
import java.lang.StringBuilder

class MainActivity : AppCompatActivity() {
//在这儿将视图存在数组中需要使用懒加载,
//对象的创建:-》(构造方法——》init方法,属性的创建——》oncreate{setContentView})
//只有在create()方法结束之后,该类的对象及其所有的属性才会被初始化完毕
//懒加载是只用在用的时候才会用 ,懒加载必须要用val
//val->不能再被另外赋值,不可变,var——》还可变的,能够被赋予相同类型的其他值

//跳转到相机的请求码
private val REQUEST_IMGE_CODE = 1

//保存所有被点亮的点
private val allselectedView = arrayListOf<ImageView>()
//保存密码
private val password = StringBuilder()
//保存线的tag值
private val allslineTag = arrayOf(12,23,45,56,78,89,
14,25,36,47,58,69,15,26,48,59,24,35,57,68)
//用于记录上一个的圆点
private var lastDot:ImageView? = null

private val dots:Array<ImageView>by lazy {
arrayOf(sdot1,sdot2,sdot3,sdot4,sdot5,sdot6,sdot7,sdot8,sdot9)
}
//算出导航栏的高度,因为导航栏的高度是固定的,所以可以只算一次就好了,就可以用懒加载了
//懒加载只加载一次
private val barHeight:Int by lazy {
//获取屏幕的高度度
val display = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(display)
//获取绘制区域的高度
val drawingRect = Rect()
window.findViewById<ViewGroup>(Window.ID_ANDROID_CONTENT).getDrawingRect(drawingRect)
return@lazy display.heightPixels-drawingRect.height()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//保存图片
File(filesDir,"header.jpg").also {
if (it.exists()){
BitmapFactory.decodeFile("${filesDir.path}/header.jpg").also {img->
headerImage.setImageBitmap(img)
}
}
}
SharePrefrenceUtil.getInstance(this).getPassword().apply {
if (this == null){
pwdText.text = "请绘制密码"
}else{
pwdText.text = "请输入密码"
}
}

headerImage.setOnClickListener {
Intent().apply{
action = Intent.ACTION_PICK
setType("image/*")
}.also {
startActivityForResult(it,REQUEST_IMGE_CODE)
}
}
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_IMGE_CODE){
if (resultCode == Activity.RESULT_OK) {
data?.data?.let {
//将图片写入本地
contentResolver.openInputStream(it).use {
//bitmap
BitmapFactory.decodeStream(it).also {image->
//显示图片
headerImage.setImageBitmap(image)
//将图片缓存起来
val file = File(filesDir,"header.jpg")
FileOutputStream(file).also {fos->
//将图片缓存到fos对应的路径中
image.compress(Bitmap.CompressFormat.JPEG,50,fos)
}
}
}
}
}
}
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
val point = event?.let { toMContainer(it) }
//限制点击事件接收的区域
if ((point?.x!! >=0&& point.x <mcontainer.width)&&
(point.y >=0&& point.y <=mcontainer.height)){
when(event.action){
MotionEvent.ACTION_DOWN->{
//改变视图状态
findPointContainsView(point)?.apply {
higheLigheView(this)
}
// pointInview(point).apply {
// if (this != null){
// visibility = View.VISIBLE
// }
// }
}
MotionEvent.ACTION_MOVE->{
//改变视图状态
findPointContainsView(point)?.apply {
higheLigheView(this)
}
// pointInview(point).apply {
// if (this != null){
// Log.v("lfl","进来了")
// setVisible(true)
// }else{
// Log.v("lfl","视图为空")
// }
// }
}
MotionEvent.ACTION_UP->reset()
}

}
return true
}


//获取视图对应的rect
private fun getRectForView(v:ImageView) = Rect(v.left,v.top,v.right,v.bottom)
//查询当前的触摸点所在的圆点
private fun findPointContainsView(point: Point):ImageView?{
for (img in dots){
if (getRectForView(img).contains(point.x,point.y)){
return img
}
}
return null
}

// //将判断被点的位置是否在圆点视图内
// private fun pointInview(point: Point):ImageView?{
// for (imag in dots){
// orPoint(Rect(imag.left,imag.top,imag.right,imag.bottom),point).apply {
// if (true){
// return imag
// }
// }
// }
// return null
// }

//判断点是否在某一个点内
// private fun orPoint(rect: Rect,point: Point):Boolean{
// if (rect.contains(point.x,point.y)){
// return true
// }
// return false
// }
//将event点的坐标转换为相对于圆点父容器的坐标
private fun toMContainer(event: MotionEvent):Point{
return Point().apply {
x = (event.x - mcontainer.x).toInt()
y = (event.y-barHeight-mcontainer.y).toInt()
}
}
//点亮视图
private fun higheLigheView(v:ImageView){
if (lastDot == null){
if (v.visibility != View.VISIBLE){
v.visibility = View.VISIBLE
//lastDot指在该视图上
lastDot = v
//将点亮的视图加入到被点亮的视图中
allselectedView.add(v)
//拼接密码
password.append(v.tag)
}
}else{
val lastTag = lastDot?.tag.toString().toInt()
val newTag = v.tag.toString().toInt()
if (lastTag>newTag){
val tempTag = newTag*10+lastTag
//遍列tag值,
for (tag in allslineTag){
if (tag == tempTag){
val view= mcontainer.findViewWithTag<ImageView>(tag.toString())
if (view != null){
view.visibility = View.VISIBLE
v.visibility = View.VISIBLE
allselectedView.add(view)
lastDot = v
allselectedView.add(v)
password.append(v.tag) }

}
}
}else{
val tempTag = lastTag*10 + newTag
//遍列tag值,
for (tag in allslineTag){
if (tag == tempTag){
val view = mcontainer.findViewWithTag<ImageView>(tag.toString())
if (view != null){
view.visibility = View.VISIBLE
v.visibility = View.VISIBLE
allselectedView.add(view)
lastDot = v
allselectedView.add(v)
password.append(v.tag)
}

}
}
}
}
}
//还原操作
private fun reset(){
SharePrefrenceUtil.getInstance(this).apply {
getPassword().also {
if (it == null){
savePassword(password.toString())
pwdText.text = "请确认密码"
}else{
if (it == password.toString()){
pwdText.text = "输入密码成功"
}else{
clearpassword()
pwdText.text = "请重新绘制密码"
}
}
}
}
for (iteam in allselectedView){
iteam.visibility = View.INVISIBLE
}
//清空 这两个并不是用来保存密码的,是记录密码的,记录密码看是否与保存的密码相同
allselectedView.clear()
password.clear()
lastDot = null
}
}
原文地址:https://www.cnblogs.com/luofangli/p/14598358.html