探索鸿蒙Next中强大的文本处理能力,打造更优雅的用户界面
在鸿蒙应用开发中,文本组件是构建用户界面的基础元素。无论是简单的文本展示、用户输入处理,还是复杂的富文本渲染,鸿蒙Next都提供了强大而灵活的组件支持。本文将深入介绍鸿蒙Next中输入框、富文本和属性字符串等文本组件的使用方法,帮助开发者更好地掌握这些核心功能。
1. 文本输入组件(TextInput/TextArea)
文本输入框是应用程序与用户交互的重要组件,常用于表单填写、搜索框、聊天输入等场景。
基本用法
在鸿蒙Next中,提供了两种主要的输入框组件:TextInput
(单行输入框)和TextArea
(多行输入框)1。
创建输入框的基本接口如下:
typescript
// 单行输入框 TextInput(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextInputController}) // 多行输入框 TextArea(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextAreaController})
简单示例:
typescript
// 单行输入框 TextInput() // 多行输入框 TextArea() // 带初始文本的多行输入框 TextArea({text: "我是TextArea我是TextArea我是TextArea我是TextArea"}).width(300)
设置输入类型
TextInput支持多种输入类型,通过type属性进行设置:1
typescript
// 基本输入模式(默认类型) TextInput().type(InputType.Normal) // 密码输入模式 TextInput().type(InputType.Password) // 邮箱地址输入模式 TextInput().type(InputType.Email) // 纯数字输入模式 TextInput().type(InputType.Number) // 电话号码输入模式 TextInput().type(InputType.PhoneNumber)
自定义样式与事件处理
输入框支持丰富的样式自定义和事件处理:1
typescript
TextInput({placeholder: '我是提示文本', text: '我是当前文本内容'}) .backgroundColor(Color.Pink) .onChange((value: string) => { console.info(value); }) .onFocus(() => { console.info('获取焦点'); }) .onSubmit((EnterKeyType) => { console.info(EnterKeyType + '输入法回车键的类型值') })
实战示例:登录界面
typescript
@Entry @Component struct TextInputSample { build() { Column() { TextInput({ placeholder: 'input your username' }).margin({ top: 20 }) .onSubmit((EnterKeyType) => { console.info(EnterKeyType + '输入法回车键的类型值') }) TextInput({ placeholder: 'input your password' }).type(InputType.Password).margin({ top: 20 }) .onSubmit((EnterKeyType) => { console.info(EnterKeyType + '输入法回车键的类型值') }) Button('Sign in').width(150).margin({ top: 20 }) }.padding(20) } }
2. 富文本展示
在实际应用中,我们经常需要展示包含多种样式、图片或链接的复杂文本内容。鸿蒙Next提供了多种实现富文本的方式。
使用Web组件渲染富文本
对于复杂的HTML内容,可以使用Web组件进行渲染:2
首先,在resources/rawfile
目录下创建HTML模板:
html
<!DOCTYPE html> <html> <body> <div id="content"></div> <script> // 接收原生层传入的富文本字符串 function writeHtml(htmlStr) { const sanitizedHtml = DOMPurify.sanitize(htmlStr); // XSS过滤 document.getElementById('content').innerHTML = sanitizedHtml; } </script> </body> </html>
然后在ArkTS中使用Web组件加载:
typescript
// 初始化Web控制器 controller: webview.WebviewController = new webview.WebviewController() // 组件声明 Web({ src: $rawfile('question.html'), controller: this.controller }) .width('100%') .layoutWeight(1) // 高度自适应填充 .onPageEnd(() => { if (this.item.answer) { // 执行JS函数注入数据 this.controller.runJavaScript(`writeHtml(\`${this.item.answer}\`)`) } })
使用Text与Span组合
对于简单的富文本内容,可以使用Text组件结合Span实现:5
typescript
@Entry @Component struct RichTextExample { build() { Column() { Text() { Span('这是红色文本') .fontColor(Color.Red) .fontSize(20); Span('这是蓝色文本') .fontColor(Color.Blue) .fontSize(15); Span('这是带下划线的文本') .fontColor(Color.Green) .textDecoration(TextDecorationType.Underline); } .fontSize(18) .textAlign(TextAlignment.Center) .margin({ top: 20 }); } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } }
性能优化建议
对于复杂的富文本内容,可以考虑以下优化措施:2
typescript
// 启用硬件加速提升复杂排版性能 webview.setRenderingMode(webview.RenderingMode.COMPOSITED) // 预加载常用富文本模板到内存 WebStorage webStorage = webview.getWebStorage(); webStorage.cacheHtml('template1', '<div class="template">...</div>'); // 替代innerHTML的高性能方案 function writeHtml(html) { const fragment = document.createDocumentFragment(); const parser = new DOMParser(); const nodes = parser.parseFromString(html, 'text/html').body.childNodes; fragment.append(...nodes); document.getElementById('content').replaceChildren(fragment); }
3. 属性字符串(StyledString/MutableStyledString)
属性字符串(StyledString/MutableStyledString)是鸿蒙Next中功能强大的文本标记对象,可用于字符或段落级别设置文本样式6。
创建与应用属性字符串
可以通过TextController将属性字符串附加到文本组件:9
typescript
@Entry @Component struct styled_string_demo1 { styledString1: StyledString = new StyledString("运动45分钟"); mutableStyledString1: MutableStyledString = new MutableStyledString("运动35分钟"); controller1: TextController = new TextController(); controller2: TextController = new TextController(); async onPageShow() { this.controller1.setStyledString(this.styledString1) this.controller2.setStyledString(this.mutableStyledString1) } build() { Column() { // 显示属性字符串 Text(undefined, { controller: this.controller1 }) Text(undefined, { controller: this.controller2 }) } .width('100%') } }
注意:推荐在onPageShow
中触发绑定,在aboutToAppear
中调用setStyledString
无法实现页面初始即可见属性字符串文本内容,因为aboutToAppear
运行时组件还没有完成创建并成功挂载节点树6。
设置文本样式
属性字符串支持多种样式设置,包括字体、阴影、装饰线等:9
typescript
// 创建文本字体样式 @Entry @Component struct styled_string_demo2 { textStyleAttrs: TextStyle = new TextStyle({ fontWeight: FontWeight.Bolder, fontSize: LengthMetrics.vp(24), fontStyle: FontStyle.Italic }) mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟 目标达成", [ { start: 2, length: 2, styledKey: StyledStringKey.FONT, styledValue: this.textStyleAttrs }, { start: 7, length: 4, styledKey: StyledStringKey.FONT, styledValue: new TextStyle({ fontColor: Color.Orange, fontSize: LengthMetrics.vp(12)}) } ]); controller: TextController = new TextController(); async onPageShow() { this.controller.setStyledString(this.mutableStyledString) } build() { Column() { // 显示属性字符串 Text(undefined, { controller: this.controller }) .margin({ top: 10 }) } .width('100%') } }
文本阴影与装饰效果
typescript
// 文本阴影效果 @Entry @Component struct styled_string_demo3 { mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [ { start: 0, length: 3, styledKey: StyledStringKey.TEXT_SHADOW, styledValue: new TextShadowStyle({ radius: 5, type: ShadowType.COLOR, color: Color.Red, offsetX: 10, offsetY: 10 }) } ]); controller: TextController = new TextController(); async onPageShow() { this.controller.setStyledString(this.mutableStyledString) } build() { Column() { // 显示属性字符串 Text(undefined, { controller: this.controller }) } .width('100%') } } // 文本装饰线 @Entry @Component struct styled_string_demo4 { mutableStyledString: MutableStyledString = new MutableStyledString("运动35分钟", [ { start: 0, length: 3, styledKey: StyledStringKey.DECORATION, styledValue: new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Red }) } ]); controller: TextController = new TextController(); async onPageShow() { this.controller.setStyledString(this.mutableStyledString) } build() { Column() { // 显示属性字符串 Text(undefined, { controller: this.controller }) } .width('100%') } }
从HTML转换
属性字符串支持将HTML格式字符串转换为属性字符串:6
typescript
// 将HTML格式字符串转换成属性字符串 StyledString.fromHtml(html: string): Promise<StyledString>
当前支持转换的HTML标签范围:<p>
、<span>
、<img>
。仅支持将这三种标签中的style属性样式转换成对应的属性字符串样式。
4. 字符串资源管理
在鸿蒙应用开发中,推荐使用字符串资源而非硬编码字符串,这有助于应用的国际化和维护3。
定义字符串资源
在string.json
文件中定义字符串资源:
json
{ "string": [ { "name": "app_name", "value": "HelloHarmony" }, { "name": "mainability_description", "value": "Java_Phone_Empty Feature Ability" }, { "name": "hello_message", "value": "你好,鸿蒙!!!" } ] }
使用字符串资源
在布局文件中使用字符串资源:
xml
<Text ohos:id="$+id:text_hello" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:background_element="$graphic:background_ability_text" ohos:text="$string:hello_message" ohos:text_size="100" />
在代码中使用字符串资源:
typescript
try { ohos.global.resource.ResourceManager resManager = getContext().getResourceManager(); String hello_msg = resManager.getElement(ResourceTable.String_hello_message).getString(); new ToastDialog(getContext()) .setText(hello_msg) .setAlignment(LayoutAlignment.BOTTOM) .show(); } catch (IOException | NotExistException | WrongTypeException e) { e.printStackTrace(); }
5. 最佳实践与注意事项
键盘避让:键盘抬起后,具有滚动能力的容器组件在横竖屏切换时,才会生效键盘避让。若希望无滚动能力的容器组件也生效键盘避让,建议在组件外嵌套一层具有滚动能力的容器组件,比如Scroll、List、Grid1。
样式优先级:当组件样式和属性字符串中的样式冲突时,冲突部分以属性字符串设置的样式为准,未冲突部分则生效组件的样式6。
性能考虑:对于复杂的富文本内容,考虑使用Web组件并结合硬件加速提升渲染性能2。
安全性:当使用Web组件渲染富文本时,务必对内容进行XSS过滤,防止安全漏洞2。
内存管理:预加载常用富文本模板到内存中可以提升性能,但需要注意内存使用情况,避免过度占用2。
结语
鸿蒙Next提供了丰富而强大的文本处理组件,从简单的文本输入到复杂的富文本渲染,都能找到合适的解决方案。通过合理使用TextInput/TextArea、StyledString/MutableStyledString以及Web组件,开发者可以创建出既美观又功能丰富的文本交互界面。
希望本文能帮助您更好地理解和使用鸿蒙Next中的文本组件,为您的应用开发提供有力支持。