文本输入组件核心讲解与实战
一、文本输入类组件核心认知一组件整体定位TextInput、TextArea、Search是鸿蒙ArkTS核心文本输入类组件基于统一输入底层能力封装支持通用样式与高频事件针对单行短文本、多行长文本、搜索专属三大场景做差异化优化是移动端应用开发必备基础组件。二核心选型原则与组件差异核心原则按输入形态和业务场景选型禁止跨场景混用。三者核心差异、专属优势与适配场景如下组件名核心特性专属优势适用场景TextInput单行输入不自动折行输入模式丰富控制器光标/选框控制能力精细账号、密码、手机号、验证码等短文本输入TextArea多行输入自动折行支持滚动适配长文本可配置自动高度/滚动条支持长文本编辑控制评论、留言、文章编辑、长备注填写Search单行输入搜索场景专属内置搜索/清除图标默认回车搜索逻辑降低自定义开发成本全局搜索、商品检索、页面内搜索栏三核心绑定规范与组件接口各组件对应专属构造函数彼此独立不通用核心接口与绑定规则如下组件名专属构造函数接口核心可选属性TextInputTextInputOptionstext: ResourceStr、controller: TextInputController、placeholder: ResourceStrTextAreaTextAreaOptionstext: ResourceStr、controller: TextAreaController、placeholder: ResourceStrSearchSearchOptionsvalue: ResourceStr、controller: SearchController、placeholder: ResourceStr、icon:string说明ResourceStr为联合类型Resource | string支持直接传入字符串或通过$r引用系统/应用资源。二、核心能力一通用事件TextInput、TextArea、Search事件触发逻辑统一仅onSubmit回调参数存在组件差异其余事件参数完全一致事件名称功能说明onChange输入内容实时变化触发用于实时校验、字数统计、数据同步、自定义过滤onSubmit按下回车/搜索键触发Search支持点击搜索按钮用于表单提交、搜索请求、内容发布onFocus组件获得焦点触发用于样式高亮、提示展示、键盘唤起前置处理onBlur组件失去焦点触发用于格式校验、样式恢复、草稿自动保存onCopy复制内容触发用于复制监控、敏感内容脱敏、操作日志记录onCut剪切内容触发用于剪切行为监控、自定义剪切逻辑onPaste粘贴内容触发用于粘贴内容校验、长度限制、格式过滤onEditChange编辑状态变化触发用于编辑状态监控、键盘显隐联动onTextSelectionChange光标/文本选中范围变化触发用于选中内容处理、光标位置联动onContentScroll内容滚动触发用于长文本滚动监控、联动布局调整onWillInsert系统输入法插入内容前触发用于前置校验、非法内容拦截onDidInsert内容插入完成触发用于格式后置修正、数据同步onWillDelete内容删除前触发用于关键内容防删、删除确认onDidDelete内容删除完成触发用于空白内容兜底、状态同步onWillChange文本即将变更触发时序晚于增删事件用于全局内容拦截、复合规则校验时序说明onWillChange执行时序晚于onWillInsert/onWillDelete早于onDidInsert/onDidDelete。二输入内容过滤三大组件支持统一过滤方案Search仅需将text绑定替换为value过滤逻辑可直接复用inputFilter原生正则过滤轻量高效适用于基础字符级规则onWillChange内容变更前拦截支持自定义逻辑适用于位置、字节、自动修正等复杂场景。1.inputFilter原生正则过滤仅需编写允许的字符集无需添加^$首尾限定符非法字符直接拦截// 仅允许字母/数字账号/验证码场景 TextInput({ text: this.content, placeholder: 请输入字母/数字 }) .inputFilter([0-9A-Za-z], (filtered) { console.log(过滤的非法内容, filtered); })2.onWillChange自定义逻辑过滤仅支持返回boolean类型true允许本次内容变更false拦截变更界面不更新如需实现内容自动修正需手动更新绑定的状态变量并返回false拦截原始输入覆盖复杂业务规则// 首位禁止输入空格 TextInput({ text: this.inputText, placeholder: 首位无空格 }) .onWillChange((changeInfo:EditableTextChangeValue){ return changeInfo.content.trimStart() ! ; })3. 组合过滤生产高频用法inputFilter做底层字符限制 onWillChange做业务规则校验兼顾性能与需求// 账号规则仅字母/数字 首位不能为数字 TextInput({ text: this.account, placeholder: 字母开头字母/数字组合 }) .inputFilter([0-9A-Za-z]) .onWillChange((newValue) { return newValue.content.replace(/^[0-9]/, ) ! ; });三组件控制器所有控制器继承自TextContentControllerBase必须与组件一对一绑定禁止跨组件混用用于光标、选框、编辑状态精细控制。1. 控制器-组件对应关系输入组件专属控制器核心能力TextInputTextInputController单行文本光标定位、选框控制、退出编辑态TextAreaTextAreaController多行文本光标定位、选框控制、长文本编辑适配SearchSearchController继承TextInputController能力适配搜索框控制2. 通用核心方法方法名称功能说明典型场景caretPosition(pos: number): void设置光标位置索引从0开始提交后光标归位、验证码输入后光标跳转setTextSelection(start: number, end: number): void获焦状态下设置文本选中区域快速选中错误文本、批量编辑前置操作stopEditing(): void退出编辑态关闭自定义键盘自定义键盘手动关闭、提交后退出编辑3. 控制器基础使用方法private inputController new TextInputController(); // 光标移至文本开头 this.inputController.caretPosition(0); // 选中0~6位字符 this.inputController.setTextSelection(0, 6); // 主动退出编辑状态 this.inputController.stopEditing();四全局焦点控制焦点控制为页面级能力与组件控制器解耦是鸿蒙标准焦点管理方案1. 核心方法核心方法功能说明参数/场景requestFocus(id: string): boolean指定ID组件获取焦点唤起输入法参数组件唯一ID场景页面自动聚焦、校验失败定位clearFocus(): void清除全页面焦点收起软键盘无参数场景点击空白处、提交/搜索完成2. 标准使用代码// 获取全局焦点控制器 const focusController this.getUIContext().getFocusController(); // 精准聚焦组件必须绑定id focusController.requestFocus(account_input); // 全局失焦收起键盘 focusController.clearFocus();注意调用requestFocus前必须为目标组件设置唯一.id(xxx)否则聚焦失效。五专属输入模式枚举强制规范各组件仅可使用自身专属枚举严禁跨组件混用。1. TextInput 专属InputType枚举成员功能说明适用场景Normal基础通用输入用户名、普通文本Number纯数字输入验证码、订单号PhoneNumber电话格式输入手机号、座机号Email邮箱格式输入邮箱登录/注册表单Password密码隐藏输入账号登录密码NUMBER_PASSWORD纯数字密码支付密码、锁屏密码USER_NAME用户名专属支持密码库填充账号登录/注册NEW_PASSWORD新密码支持强度校验密码重置、新用户注册NUMBER_DECIMAL带一位小数点数字金额、身高、体重URL网址格式输入链接填写、校验ONE_TIME_CODE一次性验证码API20短信验证码输入2. TextArea 专属TextAreaType枚举成员功能说明适用场景NORMAL基础多行输入评论、留言、长文本NUMBER纯数字多行输入长数字序列、数字备注PHONE_NUMBER电话格式多行输入批量号码录入EMAIL邮箱格式多行输入邮箱批量录入NUMBER_DECIMAL带小数点数字长文本内含数值URL网址格式长文本内含链接ONE_TIME_CODE一次性验证码API20验证码批量录入3. Search 专属SearchType枚举成员功能说明适用场景NORMAL通用搜索输入全文、关键词检索NUMBER纯数字搜索订单号、快递号、ID检索PHONE_NUMBER电话格式搜索手机号、联系电话检索EMAIL邮箱格式搜索用户邮箱检索NUMBER_DECIMAL小数搜索金额、数值区间检索URL网址搜索链接、外链检索ONE_TIME_CODE验证码检索校验码信息检索六通用回车键类型EnterKeyType三大组件通用枚举自定义软键盘回车按钮样式与语义触发后均执行onSubmit枚举成员键盘显示语义核心场景Go前往/箭头执行操作、页面跳转单输入框提交、密码框确认Search搜索/放大镜搜索触发Search组件、搜索栏Send发送内容发送聊天、评论快速发送Next下一个/右箭头切换下一个输入框表单连续输入账号→密码→验证码Done完成/对勾结束输入、收起键盘长文本编辑完成、表单最后一项输入PREVIOUS上一个/左箭头切换上一个输入框表单反向连续输入验证码→密码→账号NEW_LINE回车/换行换行/确认TextArea长文本换行、多行内容编辑三、各组件专属能力一Search 组件专属能力基于TextInput封装聚焦搜索场景提供原生图标与按钮配置属性名称功能说明实战场景searchButton右侧搜索按钮配置文字/样式点击触发onSubmit搜索栏内置提交按钮无需自定义searchIcon自定义左侧搜索图标尺寸、颜色、资源统一APP图标风格适配深色模式cancelButton清除按钮配置显隐规则、图标输入后一键清空内容二TextArea 组件专属能力聚焦多行长文本提供排版与高度控制能力属性名称功能说明实战场景minLines/maxLines最小/最大行数支持溢出滚动/截断评论区3~5行超出滚动lineSpacing行间距支持仅行间生效长文本排版优化提升可读性ellipsisMode超长文本省略位置首/中/尾非编辑态长文本预览heightAdaptivePolicy高度自适应策略动态适配输入内容高度三TextInput 组件专属能力聚焦单行表单/密码场景提供表单专属样式与交互1. 专属属性属性名称功能说明实战场景showUnderline开启下划线样式替代常规边框表单输入框简约下划线风格underlineColor配置多状态下划线颜色常态/聚焦/错误/禁用输入态高亮、错误态标红showPassword/showPasswordIcon密码显隐开关 显隐图标控制密码框一键切换可见/隐藏showUnit输入框后置单位展示需配合下划线金额框显示「元」、手机号框标注用途showError绑定错误提示文本自动展示/隐藏表单校验失败实时提示passwordRules密码生成规则透传密码保险箱新密码输入自动生成合规密码2. 专属事件事件名称功能说明实战场景onSecurityStateChange密码显隐状态切换回调同步图标状态、全局显隐联动四、工程结构基于鸿蒙6.0 API 20、Stage模型创建InputApplication工程标准目录结构如下InputApplication/ ├── AppScope/ │ └── app.json5 ├── entry/ │ ├── src/ │ │ ├── main/ │ │ │ ├── ets/ │ │ │ │ ├── entryability/ │ │ │ │ │ └── EntryAbility.ets │ │ │ │ ├── pages/ │ │ │ │ │ ├── Index.ets // 导航主页面 │ │ │ │ │ ├── InputBasicPage.ets // 示例1三大组件基础用法 │ │ │ │ │ ├── RegisterFormPage.ets // 示例2注册表单实战 │ │ │ │ │ └── InputSearchBarPage.ets // 示例3顶部搜索栏实战 │ │ │ │ │ └── CommentAreaPage.ets // 示例4评论区实战 │ │ │ ├── resources/ │ │ │ │ └── media/ // 自定义图标icon_back、search、icon_clear │ │ │ └── module.json5 │ │ └── build-profile.json5 └── build-profile.json5五、导航主页面Index.etsimport { router } from kit.ArkUI; interface RouterButton { title: string; url: string; } Entry Component struct Index { private buttonList: RouterButton[] [ { title: 示例1三大组件基础用法, url: pages/InputBasicPage }, { title: 示例2标准注册表单实战, url: pages/RegisterFormPage }, { title: 示例3顶部搜索栏实战, url: pages/InputSearchBarPage }, { title: 示例4发布评论实战, url: pages/CommentAreaPage }, ]; build() { Column({ space: 12 }) { Text(TextInput/TextArea/Search) .fontSize(30) .fontWeight(FontWeight.Bold) .margin({ bottom: 30 }); ForEach( this.buttonList, (item: RouterButton) { Button(item.title) .width(85%) .height(42) .backgroundColor($r(sys.color.brand)) .fontColor(Color.White) .borderRadius(8) .fontSize(15) .onClick(() router.pushUrl({ url: item.url })); }, (item: RouterButton) item.url ); } .width(100%) .height(100%) .justifyContent(FlexAlign.Center) .backgroundColor(#F5F5F5); } }运行效果六、示例1三大组件基础用法InputBasicPage.ets核心掌握点区分TextInput/TextArea的text绑定与Search的value绑定正确使用组件专属输入类型枚举完成核心事件绑定与数据实时同步控制器一对一绑定规范TextArea行数、行间距、溢出等长文本配置。import { router } from kit.ArkUI; interface RouterButton { title: string; url: string; } Entry Component struct Index { private buttonList: RouterButton[] [ { title: 示例1三大组件基础用法, url: pages/InputBasicPage }, { title: 示例2标准注册表单实战, url: pages/RegisterFormPage }, { title: 示例3顶部搜索栏实战, url: pages/InputSearchBarPage }, { title: 示例4发布评论实战, url: pages/CommentAreaPage }, ]; build() { Column({ space: 12 }) { Text(TextInput/TextArea/Search) .fontSize(30) .fontWeight(FontWeight.Bold) .margin({ bottom: 30 }); ForEach( this.buttonList, (item: RouterButton) { Button(item.title) .width(85%) .height(42) .backgroundColor($r(sys.color.brand)) .fontColor(Color.White) .borderRadius(8) .fontSize(15) .onClick(() router.pushUrl({ url: item.url })); }, (item: RouterButton) item.url ); } .width(100%) .height(100%) .justifyContent(FlexAlign.Center) .backgroundColor(#F5F5F5); } }运行效果七、示例2标准注册表单实战RegisterFormPage.ets核心掌握点TextInput表单场景完整配置与属性绑定inputFilter字符级过滤与业务校验密码框全局显隐双向联动实时失焦提交三层校验逻辑全局焦点控制与键盘避让表单按钮动态状态控制。Entry Component struct RegisterFormPage { State phone: string ; State pwd: string ; State confirmPwd: string ; State phoneError: string ; State pwdError: string ; State confirmPwdError: string ; State isShowPwd: boolean false; private phoneController new TextInputController(); private pwdController new TextInputController(); private confirmPwdController new TextInputController(); private showToast(message: string) { try { this.getUIContext().getPromptAction().showToast({ message, duration: 2000 }); } catch (error) {} } private validateForm(): boolean { this.phoneError this.pwdError this.confirmPwdError ; let isPass true; if (!/^1[3-9]\d{9}$/.test(this.phone.trim())) { this.phoneError this.phone ? 手机号格式错误 : 请输入手机号; isPass false; } if (this.pwd.trim().length 6 || this.pwd.trim().length 16) { this.pwdError this.pwd ? 密码长度为6-16位 : 请设置密码; isPass false; } if (this.confirmPwd.trim() ! this.pwd.trim()) { this.confirmPwdError this.confirmPwd ? 两次密码不一致 : 请确认密码; isPass false; } return isPass; } private submitRegister() { if (this.validateForm()) { this.showToast(注册成功); this.phone this.pwd this.confirmPwd ; this.isShowPwd false; this.getUIContext().getFocusController().clearFocus(); } } onPageShow(): void { try { setTimeout(() { this.getUIContext().getFocusController().requestFocus(phone_id); }, 200); } catch (error) {} } build() { Scroll() { Column({ space: 20 }) { Text(用户注册) .fontSize(28) .fontWeight(FontWeight.Bold) .margin({ top: 40, bottom: 20 }) .width(100%) .textAlign(TextAlign.Center); // 手机号输入 TextInput({ placeholder: 请输入手机号, controller: this.phoneController, text: this.phone }) .inputFilter([0-9], (filteredChars) { console.log(过滤非数字字符, filteredChars); }) .type(InputType.PhoneNumber) .maxLength(11) .width(90%) .showUnderline(true) .underlineColor({ error: #FF4D4F }) .showError(this.phoneError) .id(phone_id) .onChange((value) { this.phone value; this.phoneError ; }) .onBlur(() { if (this.phone !/^1[3-9]\d{9}$/.test(this.phone)) { this.phoneError 手机号格式错误; } }) .onSubmit(() { try { this.getUIContext().getFocusController().requestFocus(pwd_id); } catch (error) {} }); // 密码输入 TextInput({ placeholder: 请设置密码6-16位, controller: this.pwdController, text: this.pwd }) .type(InputType.Password) .maxLength(16) .width(90%) .id(pwd_id) .onWillChange((newValue) { return newValue.content.trimStart() ! ; }) .inputFilter([a-zA-Z0-9!#$%^*], (filtered) { filtered this.showToast(禁止输入${filtered}); }) .showPasswordIcon(true) .showPassword(this.isShowPwd) .onSecurityStateChange((isShowPassword: boolean) { this.isShowPwd isShowPassword; }) .onChange((value) { this.pwd value; this.pwdError ; }) .onSubmit(() { try { this.getUIContext().getFocusController().requestFocus(confirm_pwd_id); } catch (error) {} }); // 确认密码 TextInput({ placeholder: 请再次输入密码, controller: this.confirmPwdController, text: this.confirmPwd }) .type(InputType.Normal) .maxLength(16) .width(90%) .showUnderline(true) .underlineColor({ error: #FF4D4F }) .showError(this.confirmPwdError) .id(confirm_pwd_id) .inputFilter([a-zA-Z0-9!#$%^*]) .showPasswordIcon(true) .showPassword(this.isShowPwd) .onSecurityStateChange((isShowPassword: boolean) { this.isShowPwd isShowPassword; }) .onChange((value) { this.confirmPwd value; this.confirmPwdError ; }) .onSubmit(() this.submitRegister()); Row({ space: 8 }) { Checkbox() .select(this.isShowPwd) .selectedColor($r(sys.color.brand)) .onChange((v) this.isShowPwd v); Text(显示密码).fontSize(14).fontColor(#666666); } .width(90%) .margin({ top: 5 }); Button(立即注册) .width(90%) .height(45) .backgroundColor( this.phone.trim() this.pwd.trim() this.confirmPwd.trim() ? $r(sys.color.brand) : #CCCCCC ) .fontColor(Color.White) .enabled(this.phone.trim() this.pwd.trim() this.confirmPwd.trim() ? true:false) .onClick(() this.submitRegister()); } .width(100%) .alignItems(HorizontalAlign.Center); } .width(100%) .onClick(() this.getUIContext().getFocusController().clearFocus()) .backgroundColor(Color.White); } }运行效果账号-输入框样式-数字键盘密码-输入框样式—密码键盘密码-输入框样式—有图标八、示例3顶部搜索栏实战InputSearchBarPage.ets核心掌握点搜索栏标准化布局实现Search图标、按钮、输入类型完整配置实时联想词过滤与列表渲染onChangeonSubmitonBlur事件组合焦点控制与交互优化粘贴内容长度校验。import router from ohos.router; Entry Component struct InputSearchBarPage { // 搜索关键词状态 State searchKey: string ; // 联想词列表状态空数组初始值 State suggestList: string[] []; // 预设联想词库 private allSuggestWords [ ArkTS基础教程, 鸿蒙组件开发, 鸿蒙基础入门, TextInput用法, Search组件实战, 鸿蒙布局规范, ArkUI开发指南 ]; // 基础提示 private showToast(message: string) { try { this.getUIContext().getPromptAction().showToast({ message: message }); } catch (error) { // TODO: Implement error handling. } } build() { Column({ space: 0 }) { // 顶部搜索栏布局 Row({ space: 20 }) { Image($r(app.media.icon_back)) .width(25) .height(25) .objectFit(ImageFit.Contain) .onClick((){ router.back() }) // 搜索框Search专属能力配置 Search({ placeholder: 搜索本页内容..., value: this.searchKey }) .id(searchInput) .type(SearchType.NORMAL) .height(36) .placeholderFont({ size: 14 }) .enterKeyType(EnterKeyType.Search) .backgroundColor(#F5F5F5) .layoutWeight(1) .constraintSize({maxWidth:375*1.5}) .searchIcon({ color: #999, size: 18,src:$r(app.media.search)}) // 自定义搜索图标 .cancelButton({ style: CancelButtonStyle.INPUT, icon: { src: $r(app.media.icon_clear), size: 16, color: #666 } // 自定义清除图标 }) .searchButton(搜索, { fontSize: 15, fontColor: #007DFF, autoDisable: true // 无内容时按钮置灰不可点击 }) // 输入内容变化时生成联想词 .onChange((value: string) { this.searchKey value; this.getSearchSuggest(value); }) // 失去焦点时延迟清空联想词 .onBlur(() { setTimeout(() { this.suggestList []; }, 200); }) // 回车/点击搜索按钮提交 .onSubmit((searchContent: string) { this.doSearch(searchContent); this.suggestList []; this.getUIContext().getFocusController().clearFocus(); // 搜索完成全局失焦 }) // 粘贴事件校验粘贴内容格式 .onPaste((value) { if (value.length 50) { this.showToast(搜索内容不能超过50字); } }); } .width(100%) .height(60) .padding({left:15,right:15}) .justifyContent(FlexAlign.SpaceBetween) .backgroundColor(Color.White); // 联想词列表 List() { ForEach(this.suggestList, (item: string) { ListItem() { Text(item) .fontSize(14) .fontColor(#333) .padding({ left: 20, top: 12, bottom: 12 }) .width(100%) } .backgroundColor(Color.White) // 点击联想词填充搜索失焦 .onClick(() { this.searchKey item; this.doSearch(item); this.suggestList []; this.getUIContext().getFocusController().clearFocus(); }); }, (item: string) item ) } .divider({strokeWidth:1,startMargin:20,endMargin:20}) .width(100%) .height(calc(100% - 60vp)) .backgroundColor($r(sys.color.comp_background_list_card)); } .width(100%) .height(100%) .backgroundColor(#F5F5F5); } // 生成联想词方法根据输入关键词过滤预设词库 private getSearchSuggest(keyword: string) { if (!keyword || keyword.trim() ) { this.suggestList []; return; } // 不区分大小写过滤 this.suggestList this.allSuggestWords.filter(item item.toLowerCase().includes(keyword.toLowerCase()) ); } // 通用搜索方法可扩展为接口请求、内容检索等业务逻辑 private doSearch(keyword: string) { if (!keyword || keyword.trim() ) { this.showToast(请输入搜索关键词); return; } this.showToast(执行搜索${keyword}); console.log(执行搜索${keyword}); } }运行效果搜索框自定义图标回车键显示-搜索九、核心知识点总结一组件选型核心原则单行短文本账号、密码、手机号、验证码→TextInput单行不折行输入模式与控制器控制能力丰富多行长文本评论、留言、文章编辑→TextArea自动折行、支持滚动行数与排版配置完善搜索专属场景全局/页面内搜索→Search内置图标与搜索语义减少自定义开发富文本编辑 → 选用鸿蒙RichEditor不适用常规输入组件单独设计一节内容针对富文本讲解二枚举与绑定规范输入类型强绑定InputType→TextInput、TextAreaType→TextArea、SearchType→Search禁止混用数据绑定区分TextInput/TextArea使用textSearch使用value回车键类型EnterKeyType全组件通用按业务语义选择。三通用开发规范键盘避让输入页面外层嵌套Scroll避免软键盘遮挡输入过滤简单字符规则用inputFilter复杂业务规则用onWillChange可组合使用校验分层onChange清错、onBlur格式校验、submit全量校验控制器与组件一一对应禁止跨组件复用用于光标与选框精细控制焦点管理用getUIContext().getFocusController()做全局聚焦/失焦组件需绑定唯一id。四事件与交互规范onChange负责数据实时同步与基础过滤onSubmitSearch直接取searchContentTextInput/TextArea从event.text取值onPaste用于粘贴内容长度、格式校验onWillChange内容变更前置拦截支持自动修正复杂过滤首选方案。五组件专属能力要点TextInput聚焦表单与密码场景核心使用下划线、错误提示、密码显隐相关APITextArea聚焦长文本核心配置行数、行间距、高度自适应、溢出策略Search聚焦搜索场景核心使用图标定制、搜索按钮、清除按钮、空内容禁用等交互配置。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2482625.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!