基础组件大全:Text、Image、Button、TextInput的属性配置(10)
在鸿蒙 ArkTS 应用开发中,UI 的构建高度依赖于声明式范式。无论是静态展示还是动态交互,都离不开基础组件的支撑。ArkUI 框架提供了 Text、Image、Button、TextInput 四大核心基础组件。虽然它们在日常开发中使用频率极高,但如果缺乏对底层属性的深入理解,很容易写出冗余代码或导致性能瓶颈。
前言
在鸿蒙 ArkTS 应用开发中,UI 的构建高度依赖于声明式范式。无论是静态展示还是动态交互,都离不开基础组件的支撑。ArkUI 框架提供了 Text、Image、Button、TextInput 四大核心基础组件。虽然它们在日常开发中使用频率极高,但如果缺乏对底层属性的深入理解,很容易写出冗余代码或导致性能瓶颈。
一、 核心定位与适用场景对比
-
Text(文本组件):采用“纯展示”策略。主要用于渲染标题、正文、标签等静态或动态字符串。它支持富文本排版、文本截断和阴影装饰,是 UI 中最基础的视觉元素。
- 工作机制:通过链式调用设置字体样式与布局约束。
- 适用场景:所有需要文字呈现的场景,如新闻列表标题、个人中心昵称。
-
Image(图片组件):采用“资源驱动”策略。用于渲染本地图标、网络照片或 Base64 图像。它不仅负责展示,还内置了图片解码与缓存机制。
- 工作机制:根据容器尺寸与
objectFit属性进行自适应缩放裁剪。 - 适用场景:商品封面、用户头像、Banner 轮播图。
- 工作机制:根据容器尺寸与
-
Button(按钮组件):采用“事件响应”策略。作为人机交互的核心枢纽,它封装了点击态反馈与状态切换逻辑,同时支持图文混排的自定义子组件形态。
- 工作机制:监听
.onClick()回调,结合@State变量实现视图联动。 - 适用场景:表单提交、页面跳转、功能触发开关。
- 工作机制:监听
-
TextInput(单行输入框组件):采用“数据捕获”策略。专门针对用户的键盘输入行为设计,内置了光标控制、正则过滤与软键盘类型适配能力。
- 工作机制:双向绑定状态变量,实时拦截并校验非法字符。
- 适用场景:登录注册表单、全局搜索栏、验证码输入。
二、 核心属性配置详解
1. Text 文本组件
- 字体样式:通过
.fontSize(size)设定字号,.fontColor(color)设定颜色,.fontWeight(weight)控制字重(如FontWeight.Bold)。 - 排版与截断:使用
.textAlign(align)控制对齐方式;配合.maxLines(number)限制最大行数,并通过.textOverflow({overflow: TextOverflow.Ellipsis})实现超长文本的尾部省略号截断。 - 高级装饰:支持通过
.shadow()添加文字投影,以及.lineSpacing()调整多行文本的行间距以提升阅读体验。
2. Image 图片组件
- 填充模式 (objectFit):这是图片组件最核心的属性。
ImageFit.Cover保持比例覆盖容器(常用于头像);ImageFit.Contain保持比例完整显示(常用于商品图);ImageFit.Fill则强制拉伸填满边界。 - 容错与占位:通过
.alt(src)设置网络图片加载失败时的兜底占位图,避免界面出现空白裂图。 - 性能优化:对于大图,务必使用
.sourceSize({width, height})指定解码分辨率,防止内存溢出;在网络请求前需确保已申请ohos.permission.INTERNET权限。
3. Button 按钮组件
- 形态类型 (type):通过
ButtonType枚举快速生成标准外观。Capsule为胶囊型(圆角自动匹配高度一半),Circle为正圆形(需保证宽高一致),Normal为矩形(支持自定义.borderRadius())。 - 交互与状态:设置
stateEffect: true可开启默认的按压态视觉反馈;通过.enabled(boolean)动态控制按钮是否置灰禁用。 - 自定义内容:除了传入字符串,还支持在
Button() {}内部嵌套Row、Image、Text等组件,实现复杂的图文组合按钮。
4. TextInput 输入框组件
- 输入类型 (type):通过
InputType枚举调起不同的系统键盘。Password会自动掩码显示并提供明文切换图标;Number调起纯数字键盘;Email会限制仅允许输入一个@符号。 - 内容校验:使用
.maxLength(number)硬性限制最大字符数;通过.inputFilter(regex)传入正则表达式,从底层过滤非法输入(如仅允许输入中文或数字)。 - 样式定制:支持通过
.placeholder()设置灰色提示文案,.caretColor()自定义光标颜色,以及.enterKeyType()将软键盘的回车键替换为“搜索”、“发送”等业务文案。
三、 代码实战与综合应用
1. Text:从单行截断到富文本排版
除了基础的字体大小和颜色,Text 还支持多段落拼接、渐变文字以及复杂的对齐方式。
@Entry
@Component
struct AdvancedTextExample {
build() {
Column({ space: 20 }) {
// 1. 多段落拼接与独立样式控制
Text() {
Span('鸿蒙 ')
.fontSize(24)
.fontColor('#007DFF')
.fontWeight(FontWeight.Bold)
Span('ArkUI ')
.fontSize(18)
.fontColor('#666666')
Span('声明式开发范式')
.fontSize(16)
.fontColor(Color.Red)
.backgroundStyle({ color: '#FFF0F0' }) // 为特定文字添加背景色
}
.textAlign(TextAlign.Center) // 整体居中对齐
// 2. 长文本省略号 + 尾部图标(常用于新闻列表)
Row() {
Text('这是一段非常长的鸿蒙开发技术文档描述文本,用于演示超出容器宽度后的省略号截断效果及右侧图标的完美贴合。')
.fontSize(16)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.layoutWeight(1) // 占据剩余空间
Image($r('app.media.startIcon'))
.width(16).height(16)
.margin({ left: 5 })
}
.width('100%')
.alignItems(VerticalAlign.Top) // 确保文字顶部对齐小图标
// 3. 线性渐变文字(高级视觉效果)
Text('HarmonyOS NEXT')
.fontSize(36)
.fontWeight(FontWeight.Bolder)
.linearGradient({
angle: 90, // 渐变角度
colors: [['#FF0000', 0.0], ['#00FF00', 0.5], ['#0000FF', 1.0]]
})
}
.width('100%')
.padding(20)
}
}
2. Image:圆角裁剪、遮罩与占位策略
图片组件不仅是展示,还需要处理各种极端情况(如加载失败、形状裁剪)。
@Entry
@Component
struct AdvancedImageExample {
@State isLoading: boolean = true;
build() {
Column({ space: 20 }) {
// 1. 头像级圆形裁剪 + 边框 + 阴影
Image($r('app.media.background'))
.width(100)
.height(100)
.borderRadius(50) // 宽高一半即为正圆
.objectFit(ImageFit.Cover) // 保持比例覆盖,防止变形
.border({ width: 3, color: '#FFFFFF' })
.shadow({ radius: 8, color: '#33000000', offsetX: 0, offsetY: 4 })
// 2. 自定义加载状态与失败兜底 (Alt)
Stack() {
Image(this.isLoading ? '' : $r('app.media.startIcon'))
.width('100%')
.height(200)
.objectFit(ImageFit.Cover)
.onComplete(() => { this.isLoading = false; }) // 监听加载完成
.alt($r('app.media.background')) // 核心:加载失败或src为空时的占位图
if (this.isLoading) {
LoadingProgress().width(40).height(40) // 加载中显示菊花图
}
}
.width('100%')
.borderRadius(12)
// 3. 异形裁剪(例如:商品卡片顶部的半圆弧)
Image($r('app.media.background'))
.width('100%')
.height(150)
.objectFit(ImageFit.Cover)
.borderRadius({ topLeft: 0, topRight: 0, bottomLeft: 20, bottomRight: 20 })
}
.padding(20)
}
}
3. Button:图文混排、禁用态与防抖封装
原生 Button 支持嵌套任意子组件,结合 @State 可以轻松实现复杂的交互反馈。
@Entry
@Component
struct AdvancedButtonExample {
@State isSubmitting: boolean = false;
@State likeCount: number = 128;
@State isLiked: boolean = false;
build() {
Column({ space: 20 }) {
// 1. 图文混排按钮(常用于支付、分享)
Button({ type: ButtonType.Normal }) {
Row({ space: 8 }) {
Image($r('app.media.startIcon')).width(20).height(20)
Text('微信支付').fontSize(16).fontColor(Color.White)
}
}
.width('100%')
.height(48)
.backgroundColor('#07C160')
.borderRadius(8)
// 2. 动态点赞按钮(状态联动)
Button() {
Row({ space: 6 }) {
Image(this.isLiked ? $r('app.media.startIcon') : $r('app.media.background'))
.width(18).height(18)
Text(`${this.likeCount}`).fontSize(14)
}
}
.type(ButtonType.Capsule)
.backgroundColor(this.isLiked ? '#FFEDED' : '#F5F5F5')
.fontColor(this.isLiked ? '#FF4D4F' : '#666666')
.stateEffect(true) // 开启按压态缩放效果
.onClick(() => {
this.isLiked = !this.isLiked;
this.likeCount += this.isLiked ? 1 : -1;
})
// 3. 提交按钮(带 Loading 状态与防抖保护)
Button(this.isSubmitting ? '正在保存...' : '确认提交')
.type(ButtonType.Capsule)
.width('100%')
.height(48)
.enabled(!this.isSubmitting) // 关键:禁用状态下自动屏蔽点击
.opacity(this.isSubmitting ? 0.7 : 1.0) // 视觉上的置灰效果
.onClick(() => {
this.isSubmitting = true;
setTimeout(() => { this.isSubmitting = false; }, 2000); // 模拟网络请求
})
}
.padding(20)
}
}
4. TextInput:密码可见性切换、正则过滤与焦点控制
输入框是交互的重灾区,需要精细控制键盘类型、内容校验和光标行为。
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct AdvancedInputExample {
@State username: string = '';
@State password: string = '';
@State searchKey: string = '';
build() {
Column({ space: 20 }) {
// 1. 账号输入框(限制长度 + 字符过滤)
TextInput({ placeholder: '请输入账号(仅限字母数字)', text: this.username })
.type(InputType.Normal)
.maxLength(20)
.inputFilter('[a-zA-Z0-9]') // 修复:使用字符串而非 RegExp
.onChange((value: string) => { // 修复:显式声明 value 类型为 string
this.username = value;
})
.width('100%')
.height(48)
.backgroundColor('#F5F5F5')
.borderRadius(8)
.padding({ left: 15, right: 15 } as EdgeWidths) // 修复:添加类型断言避免 untyped-obj-literals
// 2. 密码输入框
TextInput({ placeholder: '请输入密码', text: this.password })
.type(InputType.Password)
.maxLength(16) // 修复:直接使用 maxLength 替代错误的 passwordRules 对象
.caretColor('#007DFF')
.placeholderColor('#CCCCCC')
.onChange((value: string) => {
this.password = value;
})
.width('100%')
.height(48)
.backgroundColor('#F5F5F5')
.borderRadius(8)
.padding({ left: 15, right: 15 } as EdgeWidths)
// 3. 搜索框
TextInput({ placeholder: '搜索商品或文章', text: this.searchKey })
.enterKeyType(EnterKeyType.Search)
.onSubmit(() => {
promptAction.showToast({ message: `开始搜索: ${this.searchKey}` });
})
.onBlur(() => {
console.log('Search input lost focus');
})
.width('100%')
.height(40)
.backgroundColor('#EEEEEE')
.borderRadius(20)
.padding({ left: 15, right: 15 } as EdgeWidths)
.fontSize(14)
}
.padding(20)
.width('100%')
}
}

四、 避坑指南与最佳实践
-
Text 的省略号陷阱
- 错误做法:只设置了
.textOverflow({overflow: TextOverflow.Ellipsis})却没有设置.maxLines()。此时文本不会生效截断,而是直接撑开容器。 - 正确做法:必须将
textOverflow与maxLines搭配使用,且建议明确指定.width()约束,否则在某些弹性布局下可能无法准确计算截断位置。
- 错误做法:只设置了
-
Image 的网络加载白屏
- 问题现象:在弱网环境下,图片加载缓慢导致界面出现大面积空白,用户体验极差。
- 解决方案:始终配置
.alt()占位图;对于列表中的大量图片,务必结合LazyForEach使用,并利用.sourceSize()限制解码尺寸,避免滑动时引发严重的内存抖动与掉帧。
-
TextInput 的安全校验缺失
- 错误做法:仅在
.onChange()回调中进行业务层的正则校验。这会导致非法字符先被输入到框内再被清除,造成光标闪烁和视觉卡顿。 - 正确做法:优先使用
.inputFilter(regex)在组件底层直接拦截非法按键输入,将.onChange()纯粹用于状态同步与业务逻辑处理。
- 错误做法:仅在
-
Button 的防抖与状态保护
- 最佳实践:涉及网络请求或耗时操作的按钮,必须在点击后立即将绑定的
@State变量设为true,并同步更新.enabled(false)或显示 Loading 状态。这能有效防止用户在等待期间连续点击导致的重复提交问题。
- 最佳实践:涉及网络请求或耗时操作的按钮,必须在点击后立即将绑定的
更多推荐



所有评论(0)