当前位置: 首页 > news >正文

《多级标签并行筛选》一、Flex弹性布局使用指南

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}from'@kit.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:boolean=false;constructor(label:string){this.label=label;}}@Entry@ComponentV2struct 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(t=>t.selected).length}个标签`).fontSize(14).fontColor('#999999')}.padding(20).width('100%').height('100%')}}

示例要点解析

  1. FlexWrap.Wrap:标签超出容器宽度时自动换行,无需手动计算每行放几个。
  2. 子项margin:通过子项的margin控制标签之间的间距,兼容性更好(详见下方注意事项)。
  3. @ObservedV2+@Trace:使用 V2 状态管理,标签选中状态变化能精确驱动 UI 更新。
  4. ForEach:动态渲染标签列表,配合稳定唯一的keyGenerator确保渲染效率。

六、Flex vs Row/Column 对比

场景推荐布局原因
单行/单列简单排列Row / Column结构清晰,属性简单
需要自动换行FlexRow 不支持换行
需要剩余空间分配FlexflexGrow/flexShrink 更灵活
需要多行对齐控制FlexalignContent 提供行级控制
简单两端对齐Row + Blank()不需要引入 Flex 全部能力

七、最佳实践

  1. 优先使用Flex处理多行流式布局:标签云、筛选项、分类导航等场景。
  2. alignContent仅在多行时生效:单行 Flex 设置alignContent无效。
  3. flexBasis优先于width/height:在主轴方向上,flexBasis会覆盖对应尺寸属性。
  4. 间距控制两种方式:使用space属性需传入LengthMetrics类型值(如LengthMetrics.vp(8)),或直接在子项上设置margin控制间距,后者兼容性更好。
  5. 配合 V2 状态管理使用@ObservedV2+@Trace能精确追踪子项状态变化,避免不必要的全量刷新。

八、总结

Flex 弹性布局是 ArkUI 中处理多方向、换行、空间分配场景的首选方案。掌握directionwrapjustifyContentalignItems四大核心属性,配合flexGrowflexShrinkflexBasis子项弹性控制,能够轻松应对绝大多数复杂排列需求。

在实际项目中,建议遵循"简单排列用 Row/Column,复杂排列用 Flex"的原则,既保持代码简洁,又充分利用 Flex 的强大能力。


参考文档:弹性布局 (Flex)

http://www.cnnetsun.cn/news/3025753.html

相关文章:

  • 全栈 API 设计与 GraphQL 实践:从 N+1 查询到 DataLoader 优化的工程化方案
  • 数据结构(六)
  • Loop 工程:从 prompter 到 loop 设计师 [翻译]
  • 2026命理软件做批量检索怎么选?八字排盘App要看标签体系和条件筛选
  • Windows热键神秘失踪案:Hotkey Detective一键破案的神奇体验
  • Kali Linux下Nikto Web扫描器实战:从原理到自动化安全评估
  • 加密算法实战指南:从对称/非对称原理到混合系统设计与密钥管理
  • LinkSwift:一键解锁九大网盘下载限速的免费解决方案
  • 告别重复操作:鸣潮自动化工具如何解放你的游戏时间
  • 【Springboot毕设全套源码+文档】基于SpringBoot的智能家居管理系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 热粘塑性材料参数识别与高效仿真:非负矩拟合与hp-FCM方法实践
  • 突破Mac文件系统壁垒:开源NTFS读写解决方案深度指南
  • JPEXS FFDec终极指南:5步掌握Flash逆向工程免费工具
  • Olist电商数据分析实战:从数据清洗到商业洞察全流程解析
  • Navicat Premium Mac无限试用终极指南:告别14天限制的完整解决方案
  • 单节点跑业务稳如泰山 扩容高可用集群反而频繁卡死 复盘完整连接交互揪出深层根因
  • 非均匀Navier-Stokes方程:密度斑块下的渐近行为与正则性分析
  • Boss直聘批量投递工具:如何用技术突破求职效率瓶颈
  • 为什么说要“买在一致”
  • 如何在Windows上免费享受Spotify Premium无广告体验完整指南
  • ncmdump:音乐格式解密专家,5分钟掌握NCM转换全流程
  • 如何快速配置PotPlayer字幕翻译插件:免费实现多语言视频无障碍观看的终极指南
  • 解决Reloaded-II模组无限下载循环的技术方案与架构优化
  • QQ音乐加密文件终极解密指南:3步解锁qmcflac/qmc0/qmc3格式
  • 股市学习心得-2026 下半年科技细分赛道个股汇总表
  • 【万字文档+源码】基于springboot+vue协作机器人门户网站-可用于毕设-课程设计-练手学习-学习资料分享
  • 为什么 printf 不写 \n 就不输出?一文吃透 glibc 标准 IO 封装全原理
  • K老答——所见皆漏
  • RTC芯片:电子系统的精准时钟与低功耗设计
  • 3D打印自制焊膏钢网:电子工程师快速原型开发利器