陵水黎族自治县网站建设_网站建设公司_轮播图_seo优化
2026/1/17 12:45:06 网站建设 项目流程

一、背景

在开发鸿蒙 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、实现效果

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询