• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 文本输入 (TextInput/TextArea)
2
3
4TextInput、TextArea是输入框组件,通常用于响应用户的输入操作,比如评论区的输入、聊天框的输入、表格的输入等,也可以结合其它组件构建功能页面,例如登录注册页面。具体用法请参考[TextInput](../reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md)、[TextArea](../reference/apis-arkui/arkui-ts/ts-basic-components-textarea.md)。
5
6
7## 创建输入框
8
9TextInput为单行输入框、TextArea为多行输入框。通过以下接口来创建。
10
11```ts
12TextInput(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextInputController})
13```
14
15```ts
16TextArea(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextAreaController})
17```
18
19- 单行输入框。
20
21  ```ts
22  TextInput()
23  ```
24
25  ![zh-cn_image_0000001511580844](figures/zh-cn_image_0000001511580844.png)
26
27
28- 多行输入框。
29
30  ```ts
31  TextArea()
32  ```
33
34  ![zh-cn_image_0000001562940481](figures/zh-cn_image_0000001562940481.png)
35
36- 多行输入框文字超出一行时会自动折行。
37
38
39  ```ts
40  TextArea({ text: "我是TextArea我是TextArea我是TextArea我是TextArea" }).width(300)
41  ```
42
43  ![zh-cn_image_0000001511580836](figures/zh-cn_image_0000001511580836.png)
44
45
46## 设置输入框类型
47
48TextInput有以下类型可选择:Normal基本输入模式、Password密码输入模式、Email邮箱地址输入模式、Number纯数字输入模式、PhoneNumber电话号码输入模式、USER_NAME用户名输入模式、NEW_PASSWORD新密码输入模式、NUMBER_PASSWORD纯数字密码输入模式、<!--Del-->SCREEN_LOCK_PASSWORD锁屏应用密码输入模式、<!--DelEnd-->NUMBER_DECIMAL带小数点的数字输入模式、带URL的输入模式。通过type属性进行设置:
49
50
51- 基本输入模式(默认类型)。
52
53  ```ts
54  TextInput()
55    .type(InputType.Normal)
56  ```
57
58  ![zh-cn_image_0000001562820765](figures/zh-cn_image_0000001562820765.png)
59
60- 密码输入模式。
61
62  ```ts
63  TextInput()
64    .type(InputType.Password)
65  ```
66
67  ![zh-cn_image_0000001511580840](figures/zh-cn_image_0000001511580840.png)
68
69- 邮箱地址输入模式。
70
71  ```ts
72  TextInput()
73    .type(InputType.Email)
74  ```
75
76  ![text_input_type_email](figures/text_input_type_email.PNG)
77
78- 纯数字输入模式。
79
80  ```ts
81  TextInput()
82    .type(InputType.Number)
83  ```
84
85  ![text_input_type_number](figures/text_input_type_number.PNG)
86
87- 电话号码输入模式。
88
89  ```ts
90  TextInput()
91    .type(InputType.PhoneNumber)
92  ```
93
94  ![text_input_type_phone_number](figures/text_input_type_phone_number.PNG)
95
96- 带小数点的数字输入模式。
97
98  ```ts
99  TextInput()
100    .type(InputType.NUMBER_DECIMAL)
101  ```
102
103  ![text_input_type_number_decimal](figures/text_input_type_number_decimal.PNG)
104
105- 带URL的输入模式。
106
107  ```ts
108  TextInput()
109    .type(InputType.URL)
110  ```
111
112  ![text_input_type_url](figures/text_input_type_url.PNG)
113
114## 自定义样式
115
116- 设置无输入时的提示文本。
117
118
119  ```ts
120  TextInput({ placeholder: '我是提示文本' })
121  ```
122
123  ![zh-cn_image_0000001511900400](figures/zh-cn_image_0000001511900400.png)
124
125
126- 设置输入框当前的文本内容。
127
128  ```ts
129  TextInput({ placeholder: '我是提示文本', text: '我是当前文本内容' })
130  ```
131
132  ![zh-cn_image_0000001562820761](figures/zh-cn_image_0000001562820761.png)
133
134- 添加backgroundColor改变输入框的背景颜色。
135
136  ```ts
137  TextInput({ placeholder: '我是提示文本', text: '我是当前文本内容' })
138    .backgroundColor(Color.Pink)
139  ```
140
141  ![zh-cn_image_0000001511740444](figures/zh-cn_image_0000001511740444.png)
142
143  更丰富的样式可以结合[通用属性](../reference/apis-arkui/arkui-ts/ts-component-general-attributes.md)实现。
144
145## 添加事件
146
147文本框主要用于获取用户输入的信息,把信息处理成数据进行上传,绑定onChange事件可以获取输入框内改变的文本内容,绑定onSubmit事件可以获取回车提交的文本信息,绑定onTextSelectionChange事件可以获取文本选中时手柄的位置信息或者编辑时光标的位置信息等等。用户也可以使用通用事件来进行相应的交互操作。
148
149>  **说明:**
150>
151>  在密码模式下,设置showPassword属性时,在onSecurityStateChange回调中,建议增加状态同步,具体详见如下示例。
152>
153> onWillInsert、onDidInsert、onWillDelete、onDidDelete回调仅支持系统输入法的场景。
154
155```ts
156TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller })
157  .type(InputType.Password)
158  .showPassword(this.passwordState)
159  .onChange((value: string) => {
160    // 文本内容发生变化时触发该回调
161    console.info('onChange is triggering: ', value);
162  })
163  .onSubmit((enterKey: EnterKeyType, event: SubmitEvent) => {
164    // 按下输入法回车键时触发该回调
165    console.info('onSubmit is triggering: ', enterKey, event.text);
166  })
167  .onTextSelectionChange((selectionStart: number, selectionEnd: number) => {
168    // 文本选择的位置发生变化或编辑状态下光标位置发生变化时,触发该回调
169    console.info('onTextSelectionChange is triggering: ', selectionStart, selectionEnd);
170  })
171  .onSecurityStateChange((isShowPassword: boolean) => {
172    // 密码显隐状态切换时,触发该回调
173    console.info('onSecurityStateChange is triggering: ', isShowPassword);
174    this.passwordState = isShowPassword;
175  })
176  .onWillInsert((info: InsertValue) => {
177    // 在将要输入时,触发该回调
178    console.info('onWillInsert is triggering: ', info.insertValue, info.insertOffset);
179    return true;
180  })
181  .onDidInsert((info: InsertValue) => {
182    // 在输入完成时,触发该回调
183    console.info('onDidInsert is triggering: ', info.insertValue, info.insertOffset);
184  })
185  .onWillDelete((info: DeleteValue) => {
186    // 在将要删除时,触发该回调
187    console.info('onWillDelete is triggering: ', info.deleteValue, info.deleteOffset);
188    return true;
189  })
190  .onDidDelete((info: DeleteValue) => {
191    // 在删除完成时,触发该回调
192    console.info('onDidDelete is triggering: ', info.deleteValue, info.deleteOffset);
193  })
194  .onFocus(() => {
195    //绑定通用事件,输入框获焦时触发该回调
196    console.info('onFocus is triggering')
197  })
198```
199
200## 选中菜单
201
202输入框中的文字被选中时会弹出包含剪切、复制、翻译、搜索的菜单。
203
204TextInput:
205```ts
206TextInput({text : '这是一段文本,用来展示选中菜单'})
207```
208![TexInput_select_menu](figures/TexInput_select_menu.jpg)
209
210TextArea:
211```ts
212TextArea({text : '这是一段文本,用来展示选中菜单'})
213```
214![TextArea_select_menu](figures/TextArea_select_menu.jpg)
215
216## 自动填充
217
218输入框可以通过[contentType](../reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md#contenttype12)属性设置自动填充类型。
219
220支持的类型请参考[ContentType](../reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md#contenttype12枚举说明)。
221```ts
222TextInput({ placeholder: '输入你的邮箱...' })
223  .width('95%')
224  .height(40)
225  .margin(20)
226  .contentType(ContentType.EMAIL_ADDRESS)
227```
228
229## 键盘避让
230
231键盘抬起后,具有滚动能力的容器组件在横竖屏切换时,才会生效键盘避让,若希望无滚动能力的容器组件也生效键盘避让,建议在组件外嵌套一层具有滚动能力的容器组件,比如[Scroll](../reference/apis-arkui/arkui-ts/ts-container-scroll.md)、[List](../reference/apis-arkui/arkui-ts/ts-container-list.md)、[Grid](../reference/apis-arkui/arkui-ts/ts-container-grid.md)。
232
233```ts
234// xxx.ets
235@Entry
236@Component
237struct Index {
238  placeHolderArr: string[] = ['1', '2', '3', '4', '5', '6', '7'];
239
240  build() {
241    Scroll() {
242      Column() {
243        ForEach(this.placeHolderArr, (placeholder: string) => {
244          TextInput({ placeholder: 'TextInput ' + placeholder })
245            .margin(30)
246        })
247      }
248    }
249    .height('100%')
250    .width('100%')
251  }
252}
253```
254
255![textinputkeyboardavoid](figures/TextInputKeyboardAvoid.gif)
256
257## 光标避让
258
259[keyBoardAvoidMode](../reference/apis-arkui/js-apis-arkui-UIContext.md#keyboardavoidmode11)枚举中的OFFSET和RESIZE在键盘抬起后,不支持二次避让。如果想要支持光标位置在点击或者通过接口设置变化后发生二次避让,可以考虑使用OFFSET_WITH_CARET和RESIZE_CARET替换原有的OFFSET和RESIZE模式。<br>
260对于滚动容器更推荐使用RESIZE_WITH_CARET,非滚动容器应该使用OFFSET_WITH_CARET。
261
262```ts
263// EntryAbility.ets
264import { KeyboardAvoidMode } from '@kit.ArkUI';
265
266// Used in UIAbility
267onWindowStageCreate(windowStage: window.WindowStage) {
268  // Main window is created, set main page for this ability
269  hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
270
271  windowStage.loadContent('pages/Index', (err, data) => {
272    let keyboardAvoidMode = windowStage.getMainWindowSync().getUIContext().getKeyboardAvoidMode();
273  windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.OFFSET_WITH_CARET);
274    if (err.code) {
275      hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
276      return;
277    }
278    hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
279  });
280}
281```
282
283```ts
284// xxx.ets
285@Entry
286@Component
287struct Index {
288  @State caretPosition: number = 600;
289  areaController: TextAreaController = new TextAreaController();
290  text = "Most of us compare ourselves with anyone we think is happier — a relative, someone we know a lot, or someone we hardly know. As a result, what we do remember is anything that makes others happy, anything that makes ourselves unhappy, totally forgetting that there is something happy in our own life.\
291  So the best way to destroy happiness is to look at something and focus on even the smallest flaw. It is the smallest flaw that would make us complain. And it is the complaint that leads to us becoming unhappy.\
292  If one chooses to be happy, he will be blessed; if he chooses to be unhappy, he will be cursed. Happiness is just what you think will make you happy.Most of us compare ourselves with anyone we think is happier — a relative, someone we know a lot, or someone we hardly know. As a result, what we do remember is anything that makes others happy, anything that makes ourselves unhappy, totally forgetting that there is something happy in our own life.\
293  ";
294
295  build() {
296    Scroll() {
297      Column() {
298        Row() {
299          Button('CaretPosition++: ' + this.caretPosition).onClick(() => {
300            this.caretPosition += 1;
301          }).fontSize(10)
302          Button('CaretPosition--: ' + this.caretPosition).onClick(() => {
303            this.caretPosition -= 1;
304          }).fontSize(10)
305          Button('SetCaretPosition: ').onClick(() => {
306            this.areaController.caretPosition(this.caretPosition);
307          }).fontSize(10)
308        }
309
310        TextArea({ text: this.text, controller: this.areaController })
311          .width('100%')
312          .fontSize('20fp')
313      }
314    }.width('100%').height('100%')
315  }
316}
317```
318
319![textinputkeyboardavoid](figures/caretavoid.gif)
320
321## 相关实例
322
323针对文本输入开发,有以下相关实例可供参考:
324
325- [聊天实例应用(ArkTS)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/IM/Chat#%E8%81%8A%E5%A4%A9%E5%AE%9E%E4%BE%8B%E5%BA%94%E7%94%A8)