news 2026/7/7 22:58:48

【HarmonyOS NEXT】如何监听软键盘的弹出和收起事件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【HarmonyOS NEXT】如何监听软键盘的弹出和收起事件

一、背景

在开发鸿蒙 APP 登录页时,当输入框键盘弹起,需要改变logo图标与输入框的间距,让整个页面完全展示,提升用户体验

二、具体问题

默认情况下,logo图标与标题栏和输入框给的固定间距,页面能够完全展示,但当键盘弹起时,输入框被遮挡,用户输入了手机号或验证码,但完全看不到自己输入的内容,很影响用户体验

问题效果预览:

问题代码示例如下:

@Extend(TextInput) function commonInputStyle(maxLength: number) { .placeholderColor('#999999') .borderRadius(8) .contentType(ContentType.PHONE_NUMBER) .caretStyle({ color: '#b35336', width: 2 }) .height(48) .maxLength(maxLength) .maxLines(1) .type(InputType.Number) .fontColor('#333333') .width("100%") .backgroundColor(Color.White) .padding({ left: 16, right: 16 }) .shadow({ radius: 4, color: '#00000008', offsetY: 2 }) } @Entry @Component export struct Index { @State phoneNumber: string = "" @State codeNumber: string = "" build() { Column() { Stack({ alignContent: Alignment.Top }) { Column() .width('100%') .height('100%') .backgroundColor('#F8F9FA') // 标题栏 Column() { Text('密码登录') .fontColor('#333333') .fontSize(20) .fontWeight(500) .margin({ top: 10 }) // logo模块 Image($r("app.media.startIcon")) .width(120) .objectFit(ImageFit.Contain) .margin({ top: 110, bottom: 60 }) .borderRadius(16) .shadow({ radius: 8, color: '#00000010', offsetY: 4 }) // 输入模块 Column() { TextInput({ text: this.phoneNumber, placeholder: "请输入手机号" }) .commonInputStyle(11) .onChange((value: string) => { this.phoneNumber = value }) TextInput({ text: this.codeNumber, placeholder: "请输入短信验证码" }) .commonInputStyle(6) .margin({ top: 20 }) .onChange((value: string) => { this.codeNumber = value }) } .width('100%') .padding({ left: 32, right: 32 }) .margin({ top: 200 }) } .width('100%') .height('100%') .justifyContent(FlexAlign.Start) } } .width('100%') .height('100%') } }

三、期望效果

当点击输入框键盘弹起时,改变logo图标与标题栏和输入框的间距,让内容能够完全展现

四、解决方案

4.1、方案1:使用输入框的焦点事件

使用输入框的焦点事件:通过TextInput组件的onFocus和onBlur事件可以间接判断键盘的弹出和收起。当输入框获得焦点时,通常会触发键盘弹出;当输入框失去焦点时,键盘会收起。

@State inputMarginTop: number = 200; // 初始值:无键盘时输入框与logo的间距 @State logoMarginTop: number = 110; //初始值:无键盘时logo与标题的间距 TextInput({ text: this.phoneNumber, placeholder: "请输入手机号" }) .commonInputStyle(11) .onChange((value: string) => { this.phoneNumber = value }) .onFocus(() => { console.log('lucy== 手机号---输入框获焦,键盘已弹出'); this.inputMarginTop = 100 this.logoMarginTop = 50 }) .onBlur(() => { console.log('lucy== 手机号---输入框失焦,键盘已收起'); this.inputMarginTop = 200 this.logoMarginTop = 110 })

备注:此种场景会有个问题,假如有多个输入框,需要给每个输入框都设置焦点事件

4.2、方案2:开启固定态软键盘高度变化的监听

监听键盘高度变化:通过window.on('keyboardHeightChange')事件可以监听键盘的高度变化。当键盘弹出时,返回的高度值为非零值;当键盘收起时,返回的高度值为0。

currentWindow.on('keyboardHeightChange', (data) => { if (data > 0) { console.info('键盘高度大于0,键盘已弹出'); } else { console.info('键盘高度为0,键盘已收起'); } });

完整示例参考如下:

import { KeyboardAvoidMode, window } from '@kit.ArkUI'; @Extend(TextInput) function commonInputStyle(maxLength: number) { .placeholderColor('#999999') .borderRadius(8) .contentType(ContentType.PHONE_NUMBER) .caretStyle({ color: '#b35336', width: 2 }) .height(48) .maxLength(maxLength) .maxLines(1) .type(InputType.Number) .fontColor('#333333') .width("100%") .backgroundColor(Color.White) .padding({ left: 16, right: 16 }) .shadow({ radius: 4, color: '#00000008', offsetY: 2 }) } @Entry @Component export struct Index { @State phoneNumber: string = "" @State codeNumber: string = "" @State inputMarginTop: number = 200; // 初始值:无键盘时输入框与logo的间距 @State logoMarginTop: number = 110; //初始值:无键盘时logo与标题的间距 aboutToAppear(): void { this.getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE); // 设置键盘避让模式 window.getLastWindow(this.getUIContext().getHostContext()).then(currentWindow => { currentWindow.on('keyboardHeightChange', (data) => { if (data > 0) { console.log('lucy== 键盘高度大于0,键盘已弹出'); this.inputMarginTop = 100 this.logoMarginTop = 50 } else { console.log('lucy== 键盘高度为0,键盘已收起'); this.inputMarginTop = 200 this.logoMarginTop = 110 } }); }); } build() { Column() { Stack({ alignContent: Alignment.Top }) { Column() .width('100%') .height('100%') .backgroundColor('#F8F9FA') // 标题栏 Column() { Text('密码登录') .fontColor('#333333') .fontSize(20) .fontWeight(500) .margin({ top: 10 }) // logo模块 Image($r("app.media.startIcon")) .width(120) .objectFit(ImageFit.Contain) .margin({ top: this.logoMarginTop, bottom: 60 }) .borderRadius(16) .shadow({ radius: 8, color: '#00000010', offsetY: 4 }) // 输入模块 Column() { TextInput({ text: this.phoneNumber, placeholder: "请输入手机号" }) .commonInputStyle(11) .onChange((value: string) => { this.phoneNumber = value }) TextInput({ text: this.codeNumber, placeholder: "请输入短信验证码" }) .commonInputStyle(6) .margin({ top: 20 }) .onChange((value: string) => { this.codeNumber = value }) } .width('100%') .padding({ left: 32, right: 32 }) .margin({ top: this.inputMarginTop }) } .width('100%') .height('100%') .justifyContent(FlexAlign.Start) } } .width('100%') .height('100%') } }

4.3、实现效果

实现效果:键盘弹起时输入框不会被遮挡

结论:我选择的是方案二,因为当输入框多的情况下,需要给每个输入框添加焦点事件,而方案二只用监听键盘的高度变化来适配间距,更适合我当下的场景

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 14:25:02

SAP ALV 显示 百分比 符号前置转换历程

FUNCTION conversion_exit_zfh_output . *"---------------------------------------------------------------------- *"*"本地接口: *" IMPORTING *" REFERENCE(INPUT) *" EXPORTING *" REFERENCE(OUTPUT) *"-…

作者头像 李华
网站建设 2026/7/4 20:40:49

深度测评专科生必用的10款AI论文工具

深度测评专科生必用的10款AI论文工具 深度测评:专科生高效写作的AI工具选择指南 在当前高等教育不断普及、学术要求日益提升的背景下,专科生在论文写作过程中常常面临时间紧张、资料查找困难、格式不规范等问题。为了帮助学生更高效地完成论文任务&#…

作者头像 李华
网站建设 2026/7/1 14:25:04

如何分析CES数据并获得2w阅读量?

上周恰逢CES 2026开展时期,作为一名关注科技创新趋势的研究者,我决定对2024-2026年三年的CES获奖数据进行一次深度分析。整个过程从数据获取到报告发布,在AI工具的加持下,效率提升了上百倍。今天我想分享一下这个完整的工作流程。…

作者头像 李华
网站建设 2026/7/4 22:36:25

智能硬件,Agent从概念走向场景的路径思考

2026年,被广泛预测为“AI终端普及元年”。产业正在告别单纯的概念验证与技术堆砌,进入“软硬一体、场景深化”的关键发展阶段。AI手机、智能眼镜、情感陪伴机器人等创新产品不再仅仅是实验室的样机,而是作为触手可及的商品,真正推…

作者头像 李华
网站建设 2026/7/4 5:20:26

‌企业级SaaS服务全模块集成测试的挑战与破局

当前行业痛点 2026年SaaS市场渗透率达78%的背景下,系统复杂度呈指数级增长。据Gartner统计,全模块集成故障导致的企业级客户流失率高达34%,主要源于三大核心矛盾: ‌环境异构性‌:混合云架构下多版本API并存&#xff…

作者头像 李华
网站建设 2026/7/1 16:27:30

Orin十年演进

下面这份内容,不是 NVIDIA 产品路线图复述,也不是算力参数对比,而是站在Orin 作为“一代自动驾驶/机器人计算平台的代表性节点”的高度,对它在未来十年中的角色演进与历史定位做一次结构性判断。🧠⚙️ Orin 十年演进&…

作者头像 李华