本节摘要:系统梳理 ArkUI 内置组件的分类地图与通用三要素(属性、事件、子组件配置),重点演示文本、按钮、图片、输入、选择器的常用参数组合,并给出布局容器的选型判据。
第 2 章已经用过三要素,但没有正面定义。任何一个 ArkUI 组件的调用都由三部分构成,以下面这段代码为标本:
Column() { Image($r('app.media.logo')) .width(64) .height(64) .borderRadius(32) .objectFit(ImageFit.Cover) Text('欢迎回来') .fontSize(20) .fontWeight(FontWeight.Medium) .maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis }) TextInput({ text: this.keyword, placeholder: '搜索' }) .onChange((v: string) => { this.keyword = v }) .onSubmit(() => { this.doSearch() }) }
三要素分别是:子组件配置——容器组件的圆括号里放子组件(Column 的括号是结构,Image 的括号是参数);属性——链式的点方法,设置尺寸、字体、圆角,每个组件都有几十上百个,但高频的就那一二十个;事件——on 开头的回调方法,响应用户交互。读任何 ArkUI 代码,先找容器结构,再看属性链,最后看事件——三分钟就能看懂一个陌生页面。
内置组件按用途分五类,每类记住几个主力即可,其余用时查文档:
| 类别 | 主力组件 | 典型场景 |
|---|---|---|
| 基础 | Text、Button、Image、TextInput、Toggle、Slider | 文字、点按、图、输入、开关、拖动条 |
| 容器 | Column、Row、Stack、Flex、List、Grid、Swiper | 排列与滚动,下一节的主体 |
| 媒体 | Video、ImageAnimator | 播放与帧动画 |
| 绘制 | Canvas、Shape 及 Circle/Rect/Path | 自定义图形、图表 |
| 栅格 | GridRow、GridCol | 响应式断点布局,3.2 节 |

组件多,参数更多,建立"手感"靠的是把高频组合用熟。挑四个最容易踩差异的:
Text 的溢出策略:长文本必须给 maxLines 与 textOverflow 配对,否则文本会把容器撑破。上面样例里的省略号写法是最常用组合;整段截断用 TextOverflow.None 配合外层 Scroll 滚动。
Image 的填充模式:objectFit 决定图片如何塞进给定宽高,Cover 保持比例裁剪、Contain 保持比例留白、Fill 拉伸变形。头像场景几乎总是 Cover + borderRadius。
TextInput 的类型:type 切换普通输入与密码;enterKeyType 决定键盘回车键的形态(搜索、下一步、完成),配合 onSubmit 构成"键盘流"操作路径,表单体验的关键细节。
Button 的型态:除了文字按钮,Button 可以包一个子组件变成任意内容的按钮(比如内部放 Row 图标加文字);控制按钮形态用 type 与 stateEffect,后者关闭后点按没有按压反馈,慎用。
事件侧同样有高频组合。除了 onChange/onClick/onSubmit,列表场景的 onTouch 与手势(Gesture,如长按、拖拽)会在 3.2 的列表里出现;页面级的手势冲突处理属于进阶话题,用到时再查即可。
背景:给应用首页做一张"消息摘要卡"——左侧头像,右侧两行文字(标题加摘要),标题右侧一个未读数角标。操作:结构上最外层 Row(横向:头像与右侧内容),右侧 Column 放两行文字,角标需要叠在标题之上,用 Stack。写成代码:
Row({ space: 12 }) { Image($r('app.media.avatar')) .width(44).height(44) .borderRadius(22) .objectFit(ImageFit.Cover) Column({ space: 4 }) { Stack({ alignContent: Alignment.BottomEnd }) { Text('项目周报') .fontSize(16).fontWeight(FontWeight.Medium) .maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis }) Text('3') .fontSize(11).fontColor('#FFFFFF') .backgroundColor('#E8402F') .borderRadius(9) .padding({ left: 6, right: 6 }) .constraintSize({ minWidth: 18 }) } Text('本周进度已同步,请查阅附件与评论区讨论') .fontSize(13).fontColor('#8A8A8A') .maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis }) } .layoutWeight(1) .alignItems(HorizontalAlign.Start) } .width('100%') .padding(12)
结果:预览器里出现一张规整的消息卡。解读两个细节:layoutWeight(1) 让右列占满头像之外的全部宽度,这是 Row 里"一固定一弹性"的标准解法;角标用 Stack 的 BottomEnd 对齐叠在标题末尾,比算坐标叠加健壮得多——标题长度变化时它始终贴着文字右侧。变式:把未读数换成时间文字,把 Stack 换成 Row + Blank(弹簧组件)同样可行,两种写法都该会。
⚠️ 常见坑:属性链里混入事件后再接属性,编译不报错但可读性崩坏。团队里约定"先属性后事件",代码评审时一眼能分区。
💡 关键直觉:选容器先问"子元素之间是什么关系"——线性关系用 Column/Row,覆盖关系用 Stack,伸缩关系用 Flex,网格与长列表关系用 Grid/List。关系答对了,属性怎么调都乱不到哪去。
本节要点回顾:
这些组件还都是静态摆设,界面里的数据从哪来、怎么滚动、怎么在手机平板上换形态,交给下一节。