文章目录
-
- 前言
- [一、Pen Kit 基础概念](#一、Pen Kit 基础概念)
-
- [1.1 模块构成](#1.1 模块构成)
- [1.2 支持的事件类型](#1.2 支持的事件类型)
- 二、回调引用管理
-
- [2.1 为什么要保存回调引用](#2.1 为什么要保存回调引用)
- [2.2 初始化回调的时机](#2.2 初始化回调的时机)
- 三、事件注册与取消
-
- [3.1 注册监听](#3.1 注册监听)
- [3.2 取消监听](#3.2 取消监听)
- [3.3 事件对象字段](#3.3 事件对象字段)
- 四、取色器的集成
-
- [4.1 工作原理](#4.1 工作原理)
- [4.2 返回值说明](#4.2 返回值说明)
- [五、UI 状态反馈设计](#五、UI 状态反馈设计)
-
- [5.1 监听状态的可视化](#5.1 监听状态的可视化)
- [5.2 事件计数器](#5.2 事件计数器)
- [5.3 Toast 即时反馈](#5.3 Toast 即时反馈)
- 六、完整生命周期流程
- 总结
前言
随着华为平板与触控笔生态的不断完善,M-Pencil 已经成为 HarmonyOS 设备上重要的输入方式之一。开发者不仅可以监听普通触摸事件,还能通过官方 Pen Kit 捕获手写笔特有的交互行为------例如笔身轻捏、悬停双击,以及结合取色器实现更丰富的创作功能。
本文以一个完整的手写笔事件测试页面为例,详细拆解 stylusInteraction 模块的注册原理、回调管理技巧,以及 imageFeaturePicker 取色器的调用方式,帮助你快速在实际项目中集成手写笔交互能力。

HarmonyOS Pen Kit 手写笔交互概览 --- M-Pencil 悬停状态下支持轻捏(squeeze)与双击(doubleTap)两种专属事件,并可结合取色器实现颜色拾取功能*

一、Pen Kit 基础概念
1.1 模块构成
HarmonyOS 的 Pen Kit(@kit.Penkit)主要包含两个核心模块:
| 模块 | 说明 | 典型用途 |
|---|---|---|
stylusInteraction |
手写笔专属交互事件 | 监听轻捏、双击等笔身操作 |
imageFeaturePicker |
图像取色器 | 在屏幕指定位置拾取颜色值 |
两个模块相互独立,可以单独使用,也可以结合使用,构建完整的手写笔辅助工具。

Pen Kit 模块架构 --- stylusInteraction 负责手写笔交互事件监听,imageFeaturePicker 提供屏幕取色能力,两者可独立或组合使用*
1.2 支持的事件类型
stylusInteraction 目前提供以下两种事件:
| 事件名 | 触发方式 | 回调类型 |
|---|---|---|
squeeze |
笔处于悬停状态时轻捏笔身按钮 | SqueezeEvent |
doubleTap |
笔处于悬停状态时双击笔身 | DoubleTapEvent |
提示:两种事件都要求手写笔处于悬停(hover)状态,即笔尖靠近但未完全按压屏幕时才能触发,普通点击状态下不会响应。
二、回调引用管理
2.1 为什么要保存回调引用
这是使用 stylusInteraction 时最容易踩坑的地方。
stylusInteraction.on() 注册监听,stylusInteraction.off() 取消监听。取消时必须传入与注册时完全相同的函数引用,否则取消操作不会生效,造成内存泄漏或重复触发。
typescript
// 在组件属性中声明,保存引用
private squeezeCallback: (event: stylusInteraction.SqueezeEvent) => void = () => {};
private doubleTapCallback: (event: stylusInteraction.DoubleTapEvent) => void = () => {};
在 aboutToAppear 中完成初始化赋值,之后注册和取消都使用这两个属性,而不是重新创建匿名函数。
提示:如果直接在
on()中写() => {}匿名函数,后续off()传入另一个匿名函数时,两者是不同引用,取消会静默失败。

回调引用管理的正确与错误方式对比 --- 左侧每次创建匿名函数导致引用不匹配、取消失败;右侧将回调保存为成员属性后,注册与取消使用同一引用,配对可靠*
2.2 初始化回调的时机
| 生命周期 | 作用 |
|---|---|
aboutToAppear |
初始化回调函数引用(赋值给成员属性) |
onPageShow |
注册事件监听(页面可见时开始监听) |
onPageHide |
取消事件监听(页面不可见时释放) |
aboutToDisappear |
兜底取消监听(防止页面销毁时资源未释放) |
这种分层设计的好处是:当用户切到其他页面时,后台页面不会继续消耗资源处理笔的事件;回到页面后自动恢复监听,体验无感知。
三、事件注册与取消
3.1 注册监听
注册时使用 try-catch 包裹是必要的。设备不支持手写笔、权限未授予等情况都会抛出异常,如果不捕获会导致应用崩溃。
typescript
stylusInteraction.on('squeeze', this.squeezeCallback);
stylusInteraction.on('doubleTap', this.doubleTapCallback);
两个事件分别用独立的 try-catch 块处理,确保一个注册失败不影响另一个。注册成功后将 isListening 标志置为 true,方便后续判断当前监听状态。
3.2 取消监听
typescript
stylusInteraction.off('squeeze', this.squeezeCallback);
stylusInteraction.off('doubleTap', this.doubleTapCallback);
取消前先检查 isListening 标志,避免在从未成功注册的情况下执行无意义的取消操作。取消完成后将标志置回 false。
3.3 事件对象字段
两种事件的回调对象均包含以下核心字段:
| 字段 | 类型 | 含义 |
|---|---|---|
timestamp |
number | 事件发生的时间戳(毫秒) |
可以将 timestamp 用于计算两次操作的时间间隔,或者在 UI 上展示最近一次操作的时刻。
四、取色器的集成
4.1 工作原理
imageFeaturePicker.pickForResult() 接收屏幕上某个点的坐标,系统会弹出取色器浮层,让用户确认拾取位置,最终以 Promise 形式返回颜色信息。
关键点在于坐标的来源。按钮的 onClick 回调携带了一个 ClickEvent 对象,其中 event.displayX 和 event.displayY 是点击位置在屏幕坐标系 中的绝对坐标,恰好符合 pickForResult 的参数要求。
typescript
.onClick((event) => {
imageFeaturePicker.pickForResult(event.displayX, event.displayY)
.then((colorInfo: imageFeaturePicker.PickedColorInfo) => {
// colorInfo.color 即拾取到的颜色值
})
.catch((err: BusinessError) => {
// 处理用户取消或设备不支持的情况
});
})
4.2 返回值说明
PickedColorInfo 对象包含的主要字段:
| 字段 | 说明 |
|---|---|
color |
拾取到的颜色值,通常为十六进制字符串(如 #FF5733) |
提示:用户点击取消按钮时,Promise 会进入
catch分支,err.code会是特定的取消错误码,需要在 catch 中区分"用户主动取消"和"真实错误",避免把取消操作误报为失败。
五、UI 状态反馈设计
5.1 监听状态的可视化
页面底部通过一行文字实时展示监听状态,颜色区分运行中与已停止:
- 绿色(
#00C853):监听运行中,手写笔事件可以被捕获 - 红色(
#FF5252):监听已停止,通常是页面切换到后台时的状态
这种设计在调试阶段非常实用,可以直观确认监听是否正常工作。
5.2 事件计数器
页面维护了两个独立的计数器变量:
squeezeCount:记录轻捏事件的累计次数doubleTapCount:记录双击事件的累计次数
每次事件触发时同步更新 lastEventInfo,展示最新一次事件的类型和时间戳,方便快速判断事件是否正常响应。
提供"重置计数器"按钮将两个计数清零,适合在多轮测试之间清空历史数据,保证测试结果的准确性。
5.3 Toast 即时反馈
每次捕获到手写笔事件时,通过 getUIContext().getPromptAction().showToast() 弹出短暂提示。
主要特点:
- 在 V2 组件体系或普通页面中,
getUIContext()是获取 UI 上下文的推荐方式,避免直接使用全局promptAction duration设置为 1500ms,时间较短,不会遮挡后续操作- 消息内容包含当前计数,让用户能立刻看到本次是第几次触发
六、完整生命周期流程
整个页面的生命周期管理可以用以下流程来理解:

Pen Kit 事件监听的完整生命周期 --- 从初始化到销毁的全流程,含页面重新进入时的循环恢复机制*
- 页面创建(
aboutToAppear):初始化回调函数引用,此时还未注册监听 - 页面显示(
onPageShow):注册squeeze和doubleTap两个监听,isListening置为true - 用户操作手写笔:事件回调触发,计数器自增,UI 更新,Toast 弹出
- 页面隐藏(
onPageHide):取消两个监听,isListening置为false,停止资源消耗 - 再次进入页面(
onPageShow):重新注册监听,无缝恢复 - 页面销毁(
aboutToDisappear):兜底执行一次取消,防止泄漏
核心优势:
- 监听与页面可见性严格绑定,后台不耗资源
- 回调引用固定保存,注册与取消配对可靠
- 每个注册/取消操作独立
try-catch,单点失败不影响整体
总结
HarmonyOS Pen Kit 的核心使用模式可以归纳为三点:在 aboutToAppear 中保存回调引用、在页面生命周期中配对注册与取消、用 try-catch 保护每一次注册操作。掌握这三点,就能安全、稳定地集成手写笔轻捏、双击等专属交互,并结合取色器等高阶功能,为用户提供更流畅的手写笔体验。