HarmonyOS ArkUI 弹性布局Flex从入门到实战完整指南本文详细介绍 HarmonyOS ArkUI 中 Flex 弹性布局的使用方法涵盖核心概念、属性配置、常见场景和完整示例代码适合 HarmonyOS 开发者快速上手。效果一、前言在 HarmonyOS ArkUI 开发中布局是构建界面的基石。当我们面对多行标签排列、自适应导航栏、剩余空间分配等需求时传统的Row/Column线性布局往往力不从心——需要手动拆分多行、计算宽度代码冗余且不易维护。Flex 弹性布局正是解决这类问题的利器。它提供了方向控制、自动换行、空间分配、交叉轴对齐等丰富能力让复杂排列需求变得简洁直观。本文将从基础概念讲起逐步深入到实际案例帮助你全面掌握 Flex 布局。二、Flex 基础概念2.1 什么是 Flex 布局Flex 布局是一种一维布局模型能够在主轴方向上灵活分配子组件的空间和间距。其核心概念包括概念说明主轴Main Axis子组件排列的主要方向由direction属性决定交叉轴Cross Axis垂直于主轴的方向Flex 容器使用Flex()创建的布局容器Flex 子项容器内的直接子组件2.2 Flex 容器创建方式Flex 容器有两种创建方式// 方式一使用 Flex 组件推荐Flex(){Text(子项1)Text(子项2)}// 方式二使用 .flexDirection() 修饰符Row(){Text(子项1)Text(子项2)}.flexDirection(FlexDirection.Row)建议在大多数场景下使用Flex()组件更直观因为它提供了完整的 Flex 属性配置。三、核心属性详解3.1 direction — 主轴方向控制子组件的排列方向Flex({direction:FlexDirection.Row}){// 水平排列默认}Flex({direction:FlexDirection.Column}){// 垂直排列}Flex({direction:FlexDirection.RowReverse}){// 水平反向排列}Flex({direction:FlexDirection.ColumnReverse}){// 垂直反向排列}3.2 wrap — 换行控制控制子组件超出主轴时是否换行值说明FlexWrap.NoWrap不换行默认子项可能被压缩FlexWrap.Wrap换行新行向交叉轴正方向排列FlexWrap.WrapReverse换行新行向交叉轴反方向排列Flex({wrap:FlexWrap.Wrap}){ForEach(tagList,(tag:string){Text(tag).padding({left:12,right:12,top:6,bottom:6}).backgroundColor(#F2F3F5).borderRadius(16)})}适用场景标签云、技能列表、分类筛选等多行排列场景。3.3 justifyContent — 主轴对齐控制子组件在主轴上的分布方式值说明FlexAlign.Start从起始端开始排列默认FlexAlign.Center居中对齐FlexAlign.End从末端开始排列FlexAlign.SpaceBetween两端对齐子项间距相等FlexAlign.SpaceAround每个子项两侧间距相等FlexAlign.SpaceEvenly所有间距包括两端完全相等Flex({justifyContent:FlexAlign.SpaceBetween}){Text(左侧)Text(中间)Text(右侧)}.width(100%)3.4 alignItems — 交叉轴对齐控制子组件在交叉轴上的对齐方式Flex({alignItems:ItemAlign.Center}){// 交叉轴居中对齐}Flex({alignItems:ItemAlign.Stretch}){// 交叉轴拉伸填充子项未设置交叉轴尺寸时生效}3.5 alignContent — 多行对齐仅在多行 Flex 布局wrap不为NoWrap中生效控制行与行之间的分布Flex({wrap:FlexWrap.Wrap,alignContent:FlexAlign.Start}){// 多行排列行与行之间从交叉轴起始端开始排列}3.6 space — 子项间距使用LengthMetrics精确设置主轴和交叉轴间距import{LengthMetrics}fromkit.ArkUI;Flex({space:{main:LengthMetrics.vp(12),// 主轴间距 12vpcross:LengthMetrics.vp(8)// 交叉轴间距 8vp}}){// 子项之间自动添加间距}四、子项弹性属性Flex 子项可以设置弹性属性控制其在主轴方向上的尺寸行为4.1 flexGrow — 剩余空间分配Flex({direction:FlexDirection.Row}){Text(固定).width(80)Text(弹性填充).flexGrow(1)// 占据剩余空间.height(40)}.width(100%)当多个子项都设置了flexGrow时剩余空间按比例分配。4.2 flexShrink — 空间不足时压缩Flex({direction:FlexDirection.Row}){Text(长文本内容可能会超出容器).flexShrink(1)// 允许压缩.flexBasis(200)Text(固定).width(80)}.width(100%)4.3 flexBasis — 主轴基准尺寸Flex({direction:FlexDirection.Row}){Text(基准100).flexBasis(100)// 主轴基准宽度 100Text(基准200).flexBasis(200)// 主轴基准宽度 200}注意flexBasis在主轴方向上会覆盖width/height设置。4.4 alignSelf — 子项独立对齐子项可以覆盖容器的alignItems设置Flex({alignItems:ItemAlign.Center}){Text(居中)Text(顶部对齐).alignSelf(ItemAlign.Start)Text(底部对齐).alignSelf(ItemAlign.End)}.height(100)五、完整示例标签筛选组件下面通过一个实际案例展示 Flex 布局在标签筛选场景中的应用ObservedV2classTagItem{Tracelabel:string;Traceselected:booleanfalse;constructor(label:string){this.labellabel;}}EntryComponentV2struct FlexTagDemo{Localtags:TagItem[][newTagItem(全部),newTagItem(推荐),newTagItem(热门),newTagItem(最新),newTagItem(收藏),newTagItem(关注),newTagItem(排行榜),newTagItem(精选)];toggleTag(tag:TagItem):void{tag.selected!tag.selected;}build(){Column({space:20}){Text(Flex 标签筛选示例).fontSize(20).fontWeight(FontWeight.Bold)// 使用 Flex 实现自动换行的标签排列Flex({wrap:FlexWrap.Wrap}){ForEach(this.tags,(tag:TagItem){Text(tag.label).fontSize(14).fontColor(tag.selected?#FFFFFF:#333333).backgroundColor(tag.selected?#4A90D9:#F2F3F5).borderRadius(20).padding({top:8,bottom:8,left:16,right:16}).margin({right:10,bottom:10}).onClick((){this.toggleTag(tag);})},(tag:TagItem)tag.label)}.width(100%)// 统计信息Text(已选择${this.tags.filter(tt.selected).length}个标签).fontSize(14).fontColor(#999999)}.padding(20).width(100%).height(100%)}}示例要点解析FlexWrap.Wrap标签超出容器宽度时自动换行无需手动计算每行放几个。子项margin通过子项的margin控制标签之间的间距兼容性更好详见下方注意事项。ObservedV2Trace使用 V2 状态管理标签选中状态变化能精确驱动 UI 更新。ForEach动态渲染标签列表配合稳定唯一的keyGenerator确保渲染效率。六、Flex vs Row/Column 对比场景推荐布局原因单行/单列简单排列Row / Column结构清晰属性简单需要自动换行FlexRow 不支持换行需要剩余空间分配FlexflexGrow/flexShrink 更灵活需要多行对齐控制FlexalignContent 提供行级控制简单两端对齐Row Blank()不需要引入 Flex 全部能力七、最佳实践优先使用Flex处理多行流式布局标签云、筛选项、分类导航等场景。alignContent仅在多行时生效单行 Flex 设置alignContent无效。flexBasis优先于width/height在主轴方向上flexBasis会覆盖对应尺寸属性。间距控制两种方式使用space属性需传入LengthMetrics类型值如LengthMetrics.vp(8)或直接在子项上设置margin控制间距后者兼容性更好。配合 V2 状态管理使用ObservedV2Trace能精确追踪子项状态变化避免不必要的全量刷新。八、总结Flex 弹性布局是 ArkUI 中处理多方向、换行、空间分配场景的首选方案。掌握direction、wrap、justifyContent、alignItems四大核心属性配合flexGrow、flexShrink、flexBasis子项弹性控制能够轻松应对绝大多数复杂排列需求。在实际项目中建议遵循简单排列用 Row/Column复杂排列用 Flex的原则既保持代码简洁又充分利用 Flex 的强大能力。参考文档弹性布局 (Flex)
《多级标签并行筛选》一、Flex弹性布局使用指南
发布时间:2026/6/27 1:11:50
HarmonyOS ArkUI 弹性布局Flex从入门到实战完整指南本文详细介绍 HarmonyOS ArkUI 中 Flex 弹性布局的使用方法涵盖核心概念、属性配置、常见场景和完整示例代码适合 HarmonyOS 开发者快速上手。效果一、前言在 HarmonyOS ArkUI 开发中布局是构建界面的基石。当我们面对多行标签排列、自适应导航栏、剩余空间分配等需求时传统的Row/Column线性布局往往力不从心——需要手动拆分多行、计算宽度代码冗余且不易维护。Flex 弹性布局正是解决这类问题的利器。它提供了方向控制、自动换行、空间分配、交叉轴对齐等丰富能力让复杂排列需求变得简洁直观。本文将从基础概念讲起逐步深入到实际案例帮助你全面掌握 Flex 布局。二、Flex 基础概念2.1 什么是 Flex 布局Flex 布局是一种一维布局模型能够在主轴方向上灵活分配子组件的空间和间距。其核心概念包括概念说明主轴Main Axis子组件排列的主要方向由direction属性决定交叉轴Cross Axis垂直于主轴的方向Flex 容器使用Flex()创建的布局容器Flex 子项容器内的直接子组件2.2 Flex 容器创建方式Flex 容器有两种创建方式// 方式一使用 Flex 组件推荐Flex(){Text(子项1)Text(子项2)}// 方式二使用 .flexDirection() 修饰符Row(){Text(子项1)Text(子项2)}.flexDirection(FlexDirection.Row)建议在大多数场景下使用Flex()组件更直观因为它提供了完整的 Flex 属性配置。三、核心属性详解3.1 direction — 主轴方向控制子组件的排列方向Flex({direction:FlexDirection.Row}){// 水平排列默认}Flex({direction:FlexDirection.Column}){// 垂直排列}Flex({direction:FlexDirection.RowReverse}){// 水平反向排列}Flex({direction:FlexDirection.ColumnReverse}){// 垂直反向排列}3.2 wrap — 换行控制控制子组件超出主轴时是否换行值说明FlexWrap.NoWrap不换行默认子项可能被压缩FlexWrap.Wrap换行新行向交叉轴正方向排列FlexWrap.WrapReverse换行新行向交叉轴反方向排列Flex({wrap:FlexWrap.Wrap}){ForEach(tagList,(tag:string){Text(tag).padding({left:12,right:12,top:6,bottom:6}).backgroundColor(#F2F3F5).borderRadius(16)})}适用场景标签云、技能列表、分类筛选等多行排列场景。3.3 justifyContent — 主轴对齐控制子组件在主轴上的分布方式值说明FlexAlign.Start从起始端开始排列默认FlexAlign.Center居中对齐FlexAlign.End从末端开始排列FlexAlign.SpaceBetween两端对齐子项间距相等FlexAlign.SpaceAround每个子项两侧间距相等FlexAlign.SpaceEvenly所有间距包括两端完全相等Flex({justifyContent:FlexAlign.SpaceBetween}){Text(左侧)Text(中间)Text(右侧)}.width(100%)3.4 alignItems — 交叉轴对齐控制子组件在交叉轴上的对齐方式Flex({alignItems:ItemAlign.Center}){// 交叉轴居中对齐}Flex({alignItems:ItemAlign.Stretch}){// 交叉轴拉伸填充子项未设置交叉轴尺寸时生效}3.5 alignContent — 多行对齐仅在多行 Flex 布局wrap不为NoWrap中生效控制行与行之间的分布Flex({wrap:FlexWrap.Wrap,alignContent:FlexAlign.Start}){// 多行排列行与行之间从交叉轴起始端开始排列}3.6 space — 子项间距使用LengthMetrics精确设置主轴和交叉轴间距import{LengthMetrics}fromkit.ArkUI;Flex({space:{main:LengthMetrics.vp(12),// 主轴间距 12vpcross:LengthMetrics.vp(8)// 交叉轴间距 8vp}}){// 子项之间自动添加间距}四、子项弹性属性Flex 子项可以设置弹性属性控制其在主轴方向上的尺寸行为4.1 flexGrow — 剩余空间分配Flex({direction:FlexDirection.Row}){Text(固定).width(80)Text(弹性填充).flexGrow(1)// 占据剩余空间.height(40)}.width(100%)当多个子项都设置了flexGrow时剩余空间按比例分配。4.2 flexShrink — 空间不足时压缩Flex({direction:FlexDirection.Row}){Text(长文本内容可能会超出容器).flexShrink(1)// 允许压缩.flexBasis(200)Text(固定).width(80)}.width(100%)4.3 flexBasis — 主轴基准尺寸Flex({direction:FlexDirection.Row}){Text(基准100).flexBasis(100)// 主轴基准宽度 100Text(基准200).flexBasis(200)// 主轴基准宽度 200}注意flexBasis在主轴方向上会覆盖width/height设置。4.4 alignSelf — 子项独立对齐子项可以覆盖容器的alignItems设置Flex({alignItems:ItemAlign.Center}){Text(居中)Text(顶部对齐).alignSelf(ItemAlign.Start)Text(底部对齐).alignSelf(ItemAlign.End)}.height(100)五、完整示例标签筛选组件下面通过一个实际案例展示 Flex 布局在标签筛选场景中的应用ObservedV2classTagItem{Tracelabel:string;Traceselected:booleanfalse;constructor(label:string){this.labellabel;}}EntryComponentV2struct FlexTagDemo{Localtags:TagItem[][newTagItem(全部),newTagItem(推荐),newTagItem(热门),newTagItem(最新),newTagItem(收藏),newTagItem(关注),newTagItem(排行榜),newTagItem(精选)];toggleTag(tag:TagItem):void{tag.selected!tag.selected;}build(){Column({space:20}){Text(Flex 标签筛选示例).fontSize(20).fontWeight(FontWeight.Bold)// 使用 Flex 实现自动换行的标签排列Flex({wrap:FlexWrap.Wrap}){ForEach(this.tags,(tag:TagItem){Text(tag.label).fontSize(14).fontColor(tag.selected?#FFFFFF:#333333).backgroundColor(tag.selected?#4A90D9:#F2F3F5).borderRadius(20).padding({top:8,bottom:8,left:16,right:16}).margin({right:10,bottom:10}).onClick((){this.toggleTag(tag);})},(tag:TagItem)tag.label)}.width(100%)// 统计信息Text(已选择${this.tags.filter(tt.selected).length}个标签).fontSize(14).fontColor(#999999)}.padding(20).width(100%).height(100%)}}示例要点解析FlexWrap.Wrap标签超出容器宽度时自动换行无需手动计算每行放几个。子项margin通过子项的margin控制标签之间的间距兼容性更好详见下方注意事项。ObservedV2Trace使用 V2 状态管理标签选中状态变化能精确驱动 UI 更新。ForEach动态渲染标签列表配合稳定唯一的keyGenerator确保渲染效率。六、Flex vs Row/Column 对比场景推荐布局原因单行/单列简单排列Row / Column结构清晰属性简单需要自动换行FlexRow 不支持换行需要剩余空间分配FlexflexGrow/flexShrink 更灵活需要多行对齐控制FlexalignContent 提供行级控制简单两端对齐Row Blank()不需要引入 Flex 全部能力七、最佳实践优先使用Flex处理多行流式布局标签云、筛选项、分类导航等场景。alignContent仅在多行时生效单行 Flex 设置alignContent无效。flexBasis优先于width/height在主轴方向上flexBasis会覆盖对应尺寸属性。间距控制两种方式使用space属性需传入LengthMetrics类型值如LengthMetrics.vp(8)或直接在子项上设置margin控制间距后者兼容性更好。配合 V2 状态管理使用ObservedV2Trace能精确追踪子项状态变化避免不必要的全量刷新。八、总结Flex 弹性布局是 ArkUI 中处理多方向、换行、空间分配场景的首选方案。掌握direction、wrap、justifyContent、alignItems四大核心属性配合flexGrow、flexShrink、flexBasis子项弹性控制能够轻松应对绝大多数复杂排列需求。在实际项目中建议遵循简单排列用 Row/Column复杂排列用 Flex的原则既保持代码简洁又充分利用 Flex 的强大能力。参考文档弹性布局 (Flex)