HarmonyOS7 UI 实战:PatternLock 九宫格图案锁屏完整实现
·

前言
手势密码解锁是很多 App 的标配——比起输密码,在九宫格上画一个图案更快也更有仪式感。ArkUI 内置了 PatternLock 组件,开箱即用的九宫格手势识别,省去了自己实现触摸轨迹计算的麻烦。
这篇文章用 PatternLock 做一个带预设图案校验的锁屏页面,顺便讲讲这个组件的各种可配置属性。
效果预览
最终效果:
- 一个 3x3 的九宫格点阵
- 手指滑动绘制图案,轨迹实时显示
- 完成后自动校验是否匹配预设图案
- 支持"设置新图案"模式
布局思路

页面结构比较清晰:
Column
├── 标题
├── PatternLock(核心组件)
├── 结果提示文本
├── 预设图案提示
└── 操作按钮(设置新图案 / 重置)
核心就是 PatternLock 组件,其他的都是辅助展示和操作。
逐步实现

PatternLock 基础配置
PatternLock()
.sideLength(260) // 组件边长
.regularColor('#E0E0E0') // 未选中点的颜色
.selectedColor('#4D96FF') // 选中点的颜色
.activeColor('#4D96FF') // 正在触摸的点的颜色
.pathColor('#4D96FF') // 轨迹线的颜色
各属性的作用一目了然。sideLength 控制整个九宫格的大小,颜色属性让你可以自定义外观风格。
图案完成回调
最关键的是 onPatternComplete 回调——用户手指抬起时触发,参数是点的索引数组:
.onPatternComplete((input: number[]) => {
// input 是用户经过的点的索引数组
// 索引从 0 到 8,对应九宫格从左到右、从上到下
// 0 1 2
// 3 4 5
// 6 7 8
})
图案校验逻辑
预设一个 “Z字形” 图案 [0, 1, 2, 5, 8],在回调中比对:
private savedPattern: number[] = [0, 1, 2, 5, 8]
.onPatternComplete((input: number[]) => {
const match = input.length === this.savedPattern.length &&
input.every((v, i) => v === this.savedPattern[i])
if (this.isSet) {
this.lockResult = '新图案已设置!'
this.isSet = false
} else if (match) {
this.lockResult = '解锁成功! 图案正确'
} else {
this.lockResult = `输入图案: ${input.join('-')} (不匹配)`
}
})
比较逻辑很简单:长度相同且每个位置的索引都一致就算匹配。
完整页面代码
@Entry
@Component
struct PatternLockPage {
@State lockResult: string = '请绘制解锁图案'
@State isSet: boolean = false
private savedPattern: number[] = [0, 1, 2, 5, 8]
build() {
Column() {
Scroll() {
Column() {
Text('PatternLock 图案锁')
.fontSize(18).fontWeight(FontWeight.Bold).margin({ bottom: 8 })
Column() {
Text('手势图案解锁')
.fontSize(14).fontWeight(FontWeight.Medium).margin({ bottom: 12 })
Column() {
PatternLock()
.sideLength(260)
.regularColor('#E0E0E0')
.selectedColor('#4D96FF')
.activeColor('#4D96FF')
.pathColor('#4D96FF')
.onPatternComplete((input: number[]) => {
const match = input.length === this.savedPattern.length &&
input.every((v, i) => v === this.savedPattern[i])
if (this.isSet) {
this.lockResult = '新图案已设置!'
this.isSet = false
} else if (match) {
this.lockResult = '解锁成功! 图案正确'
} else {
this.lockResult = `输入图案: ${input.join('-')} (不匹配)`
}
})
}
.width('100%').alignItems(HorizontalAlign.Center)
Text(this.lockResult)
.fontSize(14).fontColor('#4D96FF')
.fontWeight(FontWeight.Medium).margin({ top: 12 })
Text('预设图案: 0-1-2-5-8 (Z字形)')
.fontSize(11).fontColor('#666666').margin({ top: 4 })
Row({ space: 8 }) {
Button('设置新图案').onClick(() => {
this.isSet = true
this.lockResult = '请绘制新解锁图案'
})
Button('重置').onClick(() => {
this.lockResult = '请绘制解锁图案'
this.isSet = false
})
}
.width('100%').justifyContent(FlexAlign.SpaceEvenly)
.margin({ top: 12 })
}
.width('100%').backgroundColor('#FFFFFF').borderRadius(12).padding(16)
}
.width('100%')
}
.layoutWeight(1)
}
.width('100%').height('100%').backgroundColor('#F5F6FA').padding(16)
}
}
踩坑记录
坑1:九宫格索引顺序
九宫格的索引是:
0 1 2
3 4 5
6 7 8
从左到右、从上到下。一开始容易搞混,建议先画个草图。
坑2:图案太简单不安全
如果用户只画了两个点(如 0-1),这种"图案"太容易被猜到。可以在 onPatternComplete 中加一个最少点数校验:
if (input.length < 4) {
this.lockResult = '图案至少需要连接 4 个点'
return
}
坑3:设置新图案需要二次确认
实际应用中,设置新图案通常需要用户画两次确认一致。这个案例简化了流程,只画一次就设置成功。
写在最后
PatternLock 组件把九宫格手势识别这件事封装得很到位——不用自己处理触摸事件、轨迹计算、碰撞检测。做锁屏、手势密码、手势验证这些需求时,它是一个省心又好用的选择。
更多推荐

所有评论(0)