1# 组件随软键盘弹出避让 2 3### 介绍 4 5本示例介绍使用TextInput组件和LazyForEach实现组件随软键盘弹出避让场景。该场景多用于需要用户手动输入文字类应用。 6 7### 效果图预览 8 9<img src="./casesfeature/keyboardavoid/keyboard_avoid.gif" width="200"> 10 11**使用说明** 12 131. 进入案例时,TextInput获焦,弹出系统键盘,点击空白地方键盘收起; 142. 点击输入框触发TextInput获焦,弹出系统键盘; 153. 点击“弹出键盘”按钮触发TextInput获焦,弹出系统键盘; 164. 在上抬避让模式下, 键盘抬起时组件上抬,键盘收起后让组件恢复; 175. 在缩小避让模式下,键盘抬起时组件上抬并缩小,键盘收起后让组件恢复; 18 19### 实现思路 20 21场景一:通过设置defaultFocus属性为true,使TextInput自动获焦,完成进入案例自动拉起键盘; 22 23场景二:TextInput组件拥有点击获焦能力,输入框使用TextInput组件即可实现点击输入框弹出系统键盘; 24 25场景三:通过使用focusControl.requestFocus API实现textInput获焦拉起键盘; 26 27场景四:通过设置setKeyboardAvoidMode API,将页面的避让模式设置为RESIZE模式,,即可实现键盘拉起时组件上抬避让场景; 28 29场景五 :通过监听键盘高度,可以实时感知键盘拉起收起状态,实现缩放组件尺寸的调整,达到键盘拉起组件缩小效果,配合KeyboardAvoidMode.RESIZE避让模式,实现组件上抬缩小场景。 30 311. 创建KeyboardDataSource类,用于KeyboardAvoid和LazyForEach加载数据。源码参考[BasicDataSource.ets](./casesfeature/keyboardavoid/src/main/ets/basicDataResource/BasicDataSource.ets) 32```ts 33export class KeyboardDataSource { 34 private dataArray: string[] = []; 35 private listeners: DataChangeListener[] = []; 36 37 constructor(dataArray: string[]) { 38 for (let i = 0; i < dataArray.length; i++) { 39 this.dataArray.push(dataArray[i]); 40 } 41 } 42 public getData(index: number): string { 43 return this.dataArray[index]; 44 } 45 notifyDataReload(): void { 46 this.listeners.forEach(listener => { 47 listener.onDataReloaded(); 48 }) 49 } 50 notifyDataAdd(index: number): void { 51 this.listeners.forEach(listener => { 52 listener.onDataAdd(index); 53 }) 54 } 55// ... 56} 57``` 582. TextInput组件存在默认交互逻辑,默认即为可获焦,通过defaultFocus属性设置实现TextInput组件自动获焦。在输入按钮的点击事件中调用focusControl.requestFocus API,TextInput组件的id为方法参数,即可实现给TextInput组件申请焦点功能。源码参考[KeyboardAvoidIndex.ets](./casesfeature/keyboardavoid/src/main/ets/components/KeyboardAvoidIndex.ets) 59```ts 60TextInput() 61 .defaultFocus(true) 62 .key('keyInput') 63 64Button('输入') 65 .onClick(() => { 66 focusControl.requestFocus('keyInput'); 67 }) 68``` 693. 通过设置setKeyboardAvoidMode API,将虚拟键盘抬起时页面的避让模式设置为RESIZE模式,KeyboardAvoidMode.RESIZE是压缩Page的大小,Page下设置百分比宽高的组件会跟随Page压缩,即可实现键盘拉起时组件上抬效果。源码参考[KeyboardAvoidIndex.ets](./casesfeature/keyboardavoid/src/main/ets/components/KeyboardAvoidIndex.ets) 70 71```ts 72aboutToAppear(): void { 73 let context = getContext(this) as common.UIAbilityContext 74 context.windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE); 75 window.getLastWindow(getContext(this)).then(currentWindow => { 76 currentWindow.on('keyboardHeightChange', (data: number) => { 77 this.keyboardHeight = px2vp(data); 78 }) 79 }) 80 } 81``` 82 834. 通过监听键盘高度,可以感知到键盘的拉起收起状态,实现缩放组件尺寸的调整,配合KeyboardAvoidMode.RESIZE避让模式,实现组件上抬压缩效果。源码参考[KeyboardAvoidIndex.ets](./casesfeature/keyboardavoid/src/main/ets/components/KeyboardAvoidIndex.ets) 84 85```ts 86aboutToAppear(): void { 87 window.getLastWindow(getContext(this)).then(currentWindow => { 88 currentWindow.on('keyboardHeightChange', (data: number) => { 89 this.keyboardHeight = px2vp(data); 90 }) 91 }) 92} 93 94@Builder 95scalingContentComponent(item: string) { 96 Column() { 97 Image('') 98 .borderRadius(8) 99 .objectFit(ImageFit.Contain) 100 .width(this.keyboardHeight > 0 ? '40' : '80') 101 .height(this.keyboardHeight > 0 ? '40' : '80') 102 Text(item) 103 .fontColor(Color.Black) 104 .textAlign(TextAlign.Center) 105 .textOverflow({ overflow: TextOverflow.Ellipsis }) 106 } 107 .alignItems(HorizontalAlign.Center) 108 .justifyContent(FlexAlign.Center) 109 .width(this.keyboardHeight > 0 ? '110' : '175') 110 .height(this.keyboardHeight > 0 ? '110' : '175') 111} 112``` 113 114### 高性能知识点 115 116本示例使用了LazyForEach进行数据懒加载,[liftUpComponents布局](./casesfeature/keyboardavoid/src/main/ets/components/KeyboardAvoidIndex.ets)时会根据可视区域按需创建liftUpContentComponent组件,并在liftUpContentComponent滑出可视区域外时销毁以降低内存占用。 117 118### 工程结构&模块类型 119 120 ``` 121 keyboardavoid // har类型 122 |---pages 123 | |---KeyboardAvoidIndex.ets // 视图层-应用主页面 124 |---basicDataResource 125 | |---BasicDataSource.ets // 数据模型层-LazyForEach控制器 126 ``` 127 128### 参考资料 129 130[安全区域](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-expand-safe-area.md) 131 132[LazyForEach](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-rendering-control-lazyforeach.md) 133 134### 相关权限 135 136不涉及。 137 138### 依赖 139 140不涉及。 141 142### 约束与限制 143 1441.本示例仅支持标准系统上运行。 145 1462.本示例为Stage模型,支持API12版本SDK,SDK版本号(API Version 12 Release)。 147 1483.本示例需要使用DevEco Studio版本号(DevEco Studio 5.0.0 Release)及以上版本才可编译运行。 149 150### 下载 151 152如需单独下载本工程,执行如下命令: 153 154```shell 155git init 156git config core.sparsecheckout true 157echo code/UI/KeyboardAvoid/ > .git/info/sparse-checkout 158git remote add origin https://gitee.com/openharmony/applications_app_samples.git 159git pull origin master