摘要
输入图案密码123跳转到关于页面.
关键信息
- Android Studio:Iguana | 2023.2.1
- Gradle:distributionUrl=https://services.gradle.org/distributions/gradle-8.4-bin.zip
- jvmTarget = '1.8'
- minSdk 21
- targetSdk 34
- compileSdk 34
- 开发语言:Kotlin,Java
- ndkVersion = '21.1.6352462'
- kotlin版本:1.9.20
- kotlinCompilerExtensionVersion '1.5.4'
- com.android.library:8.3
原理简介
图案密码
[https://gitcode.com/aritraroy/patternlockview/overview]
[https://github.com/aritraroy/PatternLockView]
[https://blog.csdn.net/shenggaofei/article/details/100054501]
[https://blog.csdn.net/qq_36243942/article/details/104186126]
[https://blog.csdn.net/Joson_Wang/article/details/49929775]
[https://blog.csdn.net/octopusflying/article/details/80157204]
Android 的图案密码解锁,通过手势连接 3 * 3 的点矩阵绘制图案表示解锁密码,对应一定顺序的数字序列。
图案方式比较直观,具有易于记忆的特点。
图案密码的工作原理是将设备的屏幕划分为一系列的点或区域,用户需要按照特定的顺序在这些点或区域内滑动手指,从而形成一种独特的图案。这种图案就像一个密码一样,只有知道正确的图案才能解锁设备。
图案密码具有较高的安全性,因为它们可以组合成大量的不同图案。同时,由于图案密码直观易用,因此也受到了许多用户的欢迎。
图案密码示例 |
---|
实现
核心代码
- 修改build.gradle
/* start 图案密码库相关 */
implementation 'com.andrognito.patternlockview:patternlockview:1.0.0'
implementation 'com.andrognito.patternlockview:patternlockview-reactive:1.0.0'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.1.4'
/* end 图案密码库相关 */
- 添加PatternLockActivity页面
AndroidManifest.xml
<!-- 图案密码页 -->
<activity
android:name=".PatternLockViewActivity"
android:exported="false"
android:label="@string/title_activity_pattern_lock_view"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" />
activity_pattern_lock.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/matisse_capture_icon_color"
android:theme="@style/Theme.MaterialComponents.DayNight.NoActionBar"
android:orientation="vertical">
<ImageView
android:id="@+id/profile_image"
android:layout_width="84dp"
android:layout_height="84dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:src="@drawable/weekend_android_logo"/>
<TextView
android:id="@+id/profile_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="36dp"
android:fontFamily="sans-serif-thin"
android:gravity="center"
android:maxLines="1"
android:text="请输入页面跳转码(试一试123)"
android:textColor="@color/white"
android:textSize="20sp"/>
<com.andrognito.patternlockview.PatternLockView
android:id="@+id/pattern_lock_view"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
app:aspectRatio="square"
app:aspectRatioEnabled="true"
app:dotAnimationDuration="150"
app:dotCount="3"
app:normalStateColor="@color/white"
app:correctStateColor="@color/macaron_raspberry_cheesecake"
app:wrongStateColor="@color/pomegranate"
app:dotSelectedSize="50dp"
/>
<!-- 自定义属性-->
<!-- app:dotCount="3" // 更改行(或列)-->
<!-- app:dotNormalSize="12dp" // 更改正常状态-->
<!-- app:dotSelectedSize="24dp" // 更改选定状态-->
<!-- app:pathWidth="4dp" // 更改路径-->
<!-- app:aspectRatioEnabled="true" // 设置视图是否应该遵循自定义宽高比-->
<!-- app:aspectRatio="square" // 设置在“square”,“width_bias”,“height_bias”-->
<!-- app:normalStateColor="@color/white" // 设置正常状态下图案视图的颜色-->
<!-- app:correctStateColor="@color/primary" // 将图案视图的颜色设置为正确状态-->
<!-- app:wrongStateColor="@color/pomegranate" // 设置错误状态-->
<!-- app:dotAnimationDuration="200" // 更改动画点-->
<!-- app:pathEndAnimationDuration="100" // 更改路径结束动画的持续时间-->
</LinearLayout>
PatternLockActivity.kt
package cn.qsbye.weekend_android
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.LayoutInflater
import android.widget.TextView
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import cn.qsbye.weekend_android.AboutPageClass.MyViewModel
import cn.qsbye.weekend_android.ui.theme.WeekendAndroidTheme
import io.noties.markwon.Markwon
import com.andrognito.patternlockview.PatternLockView
import com.andrognito.patternlockview.listener.PatternLockViewListener
import com.andrognito.patternlockview.utils.PatternLockUtils
import com.andrognito.patternlockview.utils.ResourceUtils
import com.andrognito.rxpatternlockview.RxPatternLockView
import com.andrognito.rxpatternlockview.events.PatternLockCompleteEvent
import com.andrognito.rxpatternlockview.events.PatternLockCompoundEvent
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.functions.Consumer
class PatternLockViewActivity : ComponentActivity() {
// 图案密码
private lateinit var myPatternLock: MyPatternLock
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WeekendAndroidTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
// 显示图案密码
myPatternLock = MyPatternLock(this@PatternLockViewActivity)
myPatternLock.initPatternLockView()
}
}
}
} // end onCreate
}
/* start 页面布局 */
class MyPatternLock(private val context: Activity) {
// 图案密码
private lateinit var mPatternLockView: PatternLockView
@Composable
fun initPatternLockView() {
Column(
Modifier
.fillMaxSize()
.background(Color.White)
) {
/* start XML布局 */
AndroidView(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
factory = { ctx ->
val layout_from_xml =
LayoutInflater.from(ctx).inflate(R.layout.activity_pattern_lock, null)
mPatternLockView = layout_from_xml.findViewById(R.id.pattern_lock_view)
// 绑定图案密码回调
mPatternLockView.addPatternLockListener(mPatternLockViewListener)
layout_from_xml // Return the TextView instance
},
)
/* end XML布局 */
}
}
/* start 回调监听事件 */
private val mPatternLockViewListener = object : PatternLockViewListener {
override fun onStarted() {
Log.d(context::class.simpleName, "Pattern drawing started")
}
override fun onProgress(progressPattern: List<PatternLockView.Dot>) {
Log.d(
context::class.simpleName, "Pattern progress: " +
PatternLockUtils.patternToString(mPatternLockView, progressPattern)
)
}
override fun onComplete(pattern: List<PatternLockView.Dot>) {
Log.d(
context::class.simpleName, "Pattern complete: " +
PatternLockUtils.patternToString(mPatternLockView, pattern)
)
val password_to_about_activity = "123"
val patternToString = PatternLockUtils.patternToString(mPatternLockView, pattern)
if (!TextUtils.isEmpty(patternToString)) {
if (patternToString == password_to_about_activity) {
Toast.makeText(
context, "您绘制的密码是:$patternToString\n" +
"密码正确,正在进入关于页...", Toast.LENGTH_SHORT
).show()
val intent = Intent(context, AboutActivity::class.java)
context.startActivity(intent)
context.finish()
} else {
Toast.makeText(
context, "您绘制的密码是:$patternToString\n" +
"密码错误,请重新绘制", Toast.LENGTH_SHORT
).show()
}
}
}
override fun onCleared() {
Log.d(context::class.simpleName, "Pattern has been cleared")
}
}
/* end 回调监听事件 */
}
/* end 页面布局 */
效果
输入图案密码进入相应页面 |
---|