• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Web组件对接软键盘
2
3开发者能够通过Web组件对接软键盘,来处理系统软键盘的显示与交互问题,同时实现软键盘的自定义功能。主要有以下场景。
4
5- 拉起系统软键盘输入文字:用户在点击网页输入框时,会在屏幕下方弹出系统默认的软键盘(输入法),用户可以通过软键盘输入文字,输入的内容会显示在输入框中。
6- 自定义系统软键盘的回车键类型:应用指定网页输入框拉起不同类型的软键盘回车键。例如:确认、下一个、提交等。
7- 软键盘避让:在移动设备上,由于输入法通常固定在屏幕下半段,应用可设置不同的Web页面软键盘避让模式。例如:平移、调整大小、不避让等。
8- 自定义软键盘输入:在移动设备上,应用可以使用自绘制输入法在Web页面输入,以此替代系统软键盘。
9
10
11
12## Web页面输入框输入与软键盘交互的W3C标准支持
13
14为支持Web页面与系统软键盘、自定义软键盘等的良好交互,ArkWeb遵循并实现了W3C规范中的以下输入控制属性:
15- type属性
16
17  type属性定义了input元素的类型,影响输入的验证、显示方式和键盘类型。常见的type值包括:
18
19  | type值    | 描述         |
20  | -------- | ---------- |
21  | text     | 默认值。普通文本输入 |
22  | number   | 数字输入       |
23  | email    | 电子邮件地址输入   |
24  | password | 密码输入       |
25  | tel      | 电话号码输入     |
26  | url      | URL输入      |
27  | date     | 日期选择器      |
28  | time     | 时间选择器      |
29  | checkbox | 复选框        |
30  | radio    | 单选按钮       |
31  | file     | 文件上传       |
32  | submit   | 提交按钮       |
33  | reset    | 重置按钮       |
34  | button   | 普通按钮       |
35
36- inputmode属性
37
38  inputmode属性用于配置输入法类型,默认值:text。
39
40  | inputmode | 描述                                       |
41  | --------- | ---------------------------------------- |
42  | decimal   | 只显示数字键盘,通常还有一个逗号键。                        |
43  | email     | 文本键盘,键通常用于电子邮件地址,如[@]。                   |
44  | none      | 不应出现键盘。                                   |
45  | numeric   | 只显示数字键盘。                                  |
46  | search    | 文本键盘,[enter]键通常显示为[go]。                   |
47  | tel       | 只显示数字键盘,通常还有[+]、[*]和[#]键。                |
48  | text      | 默认文本键盘。                                  |
49  | url       | 文本键盘,键通常用于网址,如[.]和[/],以及特殊的[.com]键,或者其他通常用于本地设置的域名结束符。 |
50
51- enterkeyhint属性
52
53  enterkeyhint属性用于指定移动设备虚拟键盘上回车键的显示方式。
54
55  | enterkeyhint值 | 描述        |
56  | ------------- | --------- |
57  | enter         | 显示默认的回车键  |
58  | done          | 表示输入完成    |
59  | go            | 表示跳转或执行   |
60  | next          | 进入下一个输入字段 |
61  | previous      | 返回上一个输入字段 |
62  | search        | 执行搜索      |
63  | send          | 发送信息      |
64
65>**说明:**
66>
67>用户在点击网页输入框时,会在屏幕下方弹出系统默认的软键盘(输入法),并可进行文字输入上屏。
68>
69>type属性更广泛,不仅影响键盘显示,还会影响输入验证和元素的外观。
70>
71>inputmode主要用于优化移动设备上的键盘输入体验,不会改变input的基本行为或验证。
72
73
74
75## 设置软键盘避让模式
76
77在移动设备上,支持设置Web页面的软键盘避让模式。
78
791. 在应用代码中设置UIContext的软键盘避让模式[setKeyboardAvoidMode()](../reference/apis-arkui/arkui-ts/ts-universal-attributes-expand-safe-area.md#setkeyboardavoidmode11)情况下,ArkWeb组件可支持Resize和Offset两种模式。
80
81- Resize模式下,应用窗口高度可缩小避开软键盘,ArkWeb组件跟随ArkUI重新布局。
82- Offset模式下(以及默认模式),应用窗口高度不变,ArkWeb组件根据自身的避让模式进行避让。
83
84(1)在应用代码中设置UIContext的软键盘避让模式。
85
86```ts
87// EntryAbility.ets
88import { KeyboardAvoidMode } from '@kit.ArkUI';
89import { hilog } from '@kit.PerformanceAnalysisKit';
90
91onWindowStageCreate(windowStage: window.WindowStage) {
92  hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
93
94  windowStage.loadContent('pages/Index', (err, data) => {
95    let keyboardAvoidMode = windowStage.getMainWindowSync().getUIContext().getKeyboardAvoidMode();
96    // 设置虚拟键盘抬起时压缩页面大小为减去键盘的高度
97  windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE);
98    if (err.code) {
99      hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
100      return;
101    }
102    hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
103  });
104}
105```
106(2)再在Web组件中拉起软键盘。
107
108```html
109<!-- index.html -->
110<!DOCTYPE html>
111<html>
112  <head>
113    <title>测试网页</title>
114  </head>
115  <body>
116    <h1>DEMO</h1>
117    <input type="text" id="input_a">
118  </body>
119</html>
120```
121
122```ts
123//Index.ets
124import { webview } from '@kit.ArkWeb';
125
126@Entry
127@Component
128struct KeyboardAvoidExample {
129  controller: webview.WebviewController = new webview.WebviewController();
130  build() {
131    Column() {
132      Row().height("50%").width("100%").backgroundColor(Color.Gray)
133      Web({ src: $rawfile("index.html"),controller: this.controller})
134      Text("I can see the bottom of the page").width("100%").textAlign(TextAlign.Center).backgroundColor(Color.Pink).layoutWeight(1)
135    }.width('100%').height("100%")
136  }
137}
138```
139此时ArkWeb组件跟随ArkUI重新布局,效果如图1、图2所示。
140
141**图1**  Web组件网页默认软键盘避让模式
142
143![default-keyboardavoid](figures/default-keyboardavoid.png)
144
145**图2**  Web组件网页跟随Arkui软键盘避让模式
146
147![arkui-keyboardavoid](figures/arkui-keyboardavoid.png)
148
1492.在UIContext的键盘避让模式为Offset模式情况下,应用可通过[WebKeyboardAvoidMode()](../reference/apis-arkweb/ts-basic-components-web.md#webkeyboardavoidmode12)设置ArkWeb组件的键盘避让模式。[Web组件的WebKeyboardAvoidMode()接口](../reference/apis-arkweb/ts-basic-components-web.md#webkeyboardavoidmode12)优先级高于W3C侧virtualKeyboard.overlayContens150
151- RESIZE_VISUAL:仅调整可视视口的大小,而不调整布局视口的大小。
152- RESIZE_CONTENT:调整视觉视口和布局视口的大小。
153- OVERLAYS_CONTENT:不调整任何视口的大小,获焦input元素没有滚动到可识区域的行为。
154
155>**说明:**
156>
157>可视视口指用户正在看到的网站的区域,该区域的宽度等于移动设备的浏览器窗口的宽度。
158>
159>布局视口指网页本身的宽度。
160
161(1)在应用代码中设置ArkWeb的软键盘避让模式。
162
163```ts
164// Index.ets
165import { webview } from '@kit.ArkWeb';
166
167@Entry
168@Component
169struct KeyboardAvoidExample {
170  controller: webview.WebviewController = new webview.WebviewController();
171  build() {
172    Column() {
173      Row().height("50%").width("100%").backgroundColor(Color.Gray)
174      Web({ src: $rawfile("index.html"),controller: this.controller})
175        .keyboardAvoidMode(WebKeyboardAvoidMode.OVERLAYS_CONTENT) //此时ArkWeb组件不会调整任何视口的大小。
176      Text("I can see the bottom of the page").width("100%").textAlign(TextAlign.Center).backgroundColor(Color.Pink).layoutWeight(1)
177    }.width('100%').height("100%")
178  }
179}
180```
181此时ArkWeb组件根据自身的避让模式进行避让,效果如图3所示。
182
183**图3**  Web组件网页自身软键盘避让模式
184
185![web-keyboardavoid](figures/web-keyboardavoid.png)
186
187与其他Web组件行为的交叉场景:
188
189| 交叉场景         | 规格                                       |
190| ------------ | ---------------------------------------- |
191| 同层渲染         | 同层Web:软键盘避让行为与普通场景行为一致  同层系统组件:由ArkUI负责软键盘避让模式。 |
192| 离屏创建组件       | 默认使用与非离屏创建一致的软键盘避让模式 在上树前设置其他避让模式可需生效。   |
193| customDialog | customDialog自身避让。                        |
194| 折叠屏          | 软键盘避让行为与普通场景行为一致 软件键盘需跟随屏幕开合状态进展开合变化。    |
195| 软键盘托管        | 软键盘避让行为与普通场景行为一致。                        |
196| Web嵌套滚动      | 嵌套滚动场景下不推荐使用Web软键盘避让,包括RESIZE_VISUAL与RESIZE_CONTENT。 |
197
198
199
200## 拦截系统软键盘与自定义软键盘输入
201
202应用能够通过调用[onInterceptKeyboardAttach](../reference/apis-arkweb/ts-basic-components-web.md#oninterceptkeyboardattach12)来拦截系统软键盘的弹出。在网页中,当可编辑元素如input标签即将触发软键盘显示时,[onInterceptKeyboardAttach](../reference/apis-arkweb/ts-basic-components-web.md#oninterceptkeyboardattach12)会被回调。应用可利用此接口来控制软键盘的显示,包括使用系统默认软键盘、定制带有特定Enter键的软键盘,或是完全自定义软键盘。借助这一功能,开发者能够实现对软键盘的灵活管理。
203
204- 使用系统默认软键盘
205- 使用定制Enter键的系统软键盘
206- 使用完全由应用自定义的软键盘
207
208```ts
209  // Index.ets
210  import { webview } from '@kit.ArkWeb';
211  import { inputMethodEngine } from '@kit.IMEKit';
212
213  @Entry
214  @Component
215  struct WebComponent {
216    controller: webview.WebviewController = new webview.WebviewController();
217    webKeyboardController: WebKeyboardController = new WebKeyboardController()
218    inputAttributeMap: Map<string, number> = new Map([
219        ['UNSPECIFIED', inputMethodEngine.ENTER_KEY_TYPE_UNSPECIFIED],
220        ['GO', inputMethodEngine.ENTER_KEY_TYPE_GO],
221        ['SEARCH', inputMethodEngine.ENTER_KEY_TYPE_SEARCH],
222        ['SEND', inputMethodEngine.ENTER_KEY_TYPE_SEND],
223        ['NEXT', inputMethodEngine.ENTER_KEY_TYPE_NEXT],
224        ['DONE', inputMethodEngine.ENTER_KEY_TYPE_DONE],
225        ['PREVIOUS', inputMethodEngine.ENTER_KEY_TYPE_PREVIOUS]
226      ])
227
228      /**
229       * 自定义键盘组件Builder
230       */
231      @Builder
232      customKeyboardBuilder() {
233		  // 这里实现自定义键盘组件,对接WebKeyboardController实现输入、删除、关闭等操作。
234        Row() {
235          Text("完成")
236            .fontSize(20)
237            .fontColor(Color.Blue)
238            .onClick(() => {
239              this.webKeyboardController.close();
240            })
241          // 插入字符。
242          Button("insertText").onClick(() => {
243            this.webKeyboardController.insertText('insert ');
244          }).margin({
245            bottom: 200,
246          })
247          // 从后往前删除length参数指定长度的字符。
248          Button("deleteForward").onClick(() => {
249            this.webKeyboardController.deleteForward(1);
250          }).margin({
251            bottom: 200,
252          })
253          // 从前往后删除length参数指定长度的字符。
254          Button("deleteBackward").onClick(() => {
255            this.webKeyboardController.deleteBackward(1);
256          }).margin({
257            left: -220,
258          })
259          // 插入功能按键。
260          Button("sendFunctionKey").onClick(() => {
261            this.webKeyboardController.sendFunctionKey(6);
262          })
263        }
264      }
265
266    build() {
267      Column() {
268        Web({ src: $rawfile('index.html'), controller: this.controller })
269        .onInterceptKeyboardAttach((KeyboardCallbackInfo) => {
270          // option初始化,默认使用系统默认键盘
271          let option: WebKeyboardOptions = {
272            useSystemKeyboard: true,
273          };
274          if (!KeyboardCallbackInfo) {
275            return option;
276          }
277
278          // 保存WebKeyboardController,使用自定义键盘时候,需要使用该handler控制输入、删除、软键盘关闭等行为
279          this.webKeyboardController = KeyboardCallbackInfo.controller
280          let attributes: Record<string, string> = KeyboardCallbackInfo.attributes
281          // 遍历attributes
282          let attributeKeys = Object.keys(attributes)
283          for (let i = 0; i < attributeKeys.length; i++) {
284            console.log('WebCustomKeyboard key = ' + attributeKeys[i] + ', value = ' + attributes[attributeKeys[i]])
285          }
286
287          if (attributes) {
288            if (attributes['data-keyboard'] == 'customKeyboard') {
289              // 根据html可编辑元素的属性,判断使用不同的软键盘,例如这里如果属性包含有data-keyboard,且值为customKeyboard,则使用自定义键盘
290              console.log('WebCustomKeyboard use custom keyboard')
291              option.useSystemKeyboard = false;
292              // 设置自定义键盘builder
293              option.customKeyboard = () => {
294                this.customKeyboardBuilder()
295              }
296              return option;
297            }
298
299            if (attributes['keyboard-return'] != undefined) {
300              // 根据html可编辑元素的属性,判断使用不同的软键盘,例如这里如果属性包含有keyboard-return,使用系统键盘,并且指定系统软键盘enterKey类型
301              option.useSystemKeyboard = true;
302              let enterKeyType: number | undefined = this.inputAttributeMap.get(attributes['keyboard-return'])
303              if (enterKeyType != undefined) {
304                option.enterKeyType = enterKeyType
305              }
306              return option;
307            }
308          }
309
310          return option;
311        })
312      }
313    }
314  }
315```
316
317```html
318<!-- index.html -->
319    <!DOCTYPE html>
320    <html>
321
322    <head>
323        <meta charset="utf-8">
324        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0">
325    </head>
326
327    <body>
328
329    <p style="font-size:12px">input标签,原有默认行为:</p>
330    <input type="text" style="width: 300px; height: 20px"><br>
331    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
332
333    <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key UNSPECIFIED:</p>
334    <input type="text" keyboard-return="UNSPECIFIED" style="width: 300px; height: 20px"><br>
335    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
336
337    <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key GO:</p>
338    <input type="text" keyboard-return="GO" style="width: 300px; height: 20px"><br>
339    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
340
341    <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key SEARCH:</p>
342    <input type="text" keyboard-return="SEARCH" style="width: 300px; height: 20px"><br>
343    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
344
345    <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key SEND:</p>
346    <input type="text" keyboard-return="SEND" style="width: 300px; height: 20px"><br>
347    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
348
349    <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key NEXT:</p>
350    <input type="text" keyboard-return="NEXT" style="width: 300px; height: 20px"><br>
351    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
352
353    <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key DONE:</p>
354    <input type="text" keyboard-return="DONE" style="width: 300px; height: 20px"><br>
355    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
356
357    <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key PREVIOUS:</p>
358    <input type="text" keyboard-return="PREVIOUS" style="width: 300px; height: 20px"><br>
359    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
360
361    <p style="font-size:12px">input标签,应用自定义键盘:</p>
362    <input type="text" data-keyboard="customKeyboard" style="width: 300px; height: 20px"><br>
363
364    </body>
365
366    </html>
367```
368
369ArkWeb自定义键盘示例效果如图4、图5、图6所示。
370
371**图4**  ArkWeb自定义键盘数字键盘
372
373![web-customkeyboardnumber](figures/web-customkeyboardnumber.png)
374
375**图5**  ArkWeb自定义键盘字母键盘
376
377![web-customkeyboardletter](figures/web-customkeyboardletter.png)
378
379**图6**  ArkWeb自定义键盘符号键盘
380
381![web-customkeyboardsymbol](figures/web-customkeyboardsymbol.png)