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

HarmonyOS PC 应用 Flex flexBasis 详解——给子项设定一个“起点宽度“

文章目录

    • 弹性布局的第三个属性
    • flexBasis 的取值
    • 完整 Demo
    • flexBasis、flexGrow、flexShrink 三者的关系
    • PC 端仪表盘的布局建议
    • 小结

弹性布局的第三个属性

学了flexGrow(分配剩余空间)和flexShrink(压缩超出空间),还剩一个问题没解答:在伸缩之前,子项的初始尺寸是多少?

这就是flexBasis的作用:设定 Flex 子项在主轴方向上的基准尺寸,也就是伸缩计算的起始点。

flexBasis的优先级比width高。在 Flex 容器里,如果你同时设了width(100)flexBasis('30%'),布局计算时以flexBasis为准。

在 PC 端仪表盘场景里,flexBasis非常有用:你可以给不同的数据卡片设置不同的基准宽度,组合出各种布局模式,再配合flexGrow让它们在剩余空间内弹性伸展。

flexBasis 的取值

flexBasis接受两类值:

// 像素值(vp).flexBasis(200)// 基准宽度 200vp// 百分比字符串.flexBasis('50%')// 基准宽度是父容器的 50%// 'auto'(默认值).flexBasis('auto')// 以 width 属性为准

完整 Demo

新建文件PcFlexBasisPage.ets

// PcFlexBasisPage.ets// HarmonyOS PC 端仪表盘 — flexBasis 四种布局模式演示interfaceDashCard{id:number;title:stringvalue:stringunit:stringtrend:number// 正值上升,负值下降color:stringbasis?:string// flexBasis 值}interfaceLayoutModeParams{id:numbername:stringdesc:stringbases:string[]// 每张卡片的 flexBasis 值}@Entry@Componentstruct PcFlexBasisPage{@StatecurrentMode:number=0privatecards:DashCard[]=[{id:1,title:'今日活跃用户',value:'128,450',unit:'人',trend:12.3,color:'#0A59F7'},{id:2,title:'本月新增用户',value:'23,890',unit:'人',trend:-2.1,color:'#00B578'},{id:3,title:'应用崩溃率',value:'0.12',unit:'%',trend:-0.03,color:'#FF7A00'},{id:4,title:'平均响应时间',value:'186',unit:'ms',trend:8.5,color:'#8B5CF6'},{id:5,title:'今日收入',value:'¥45,320',unit:'',trend:18.7,color:'#EF4444'},]privatelayoutModes:LayoutModeParams[]=[{id:0,name:'自适应',desc:'flexBasis: auto',bases:['auto','auto','auto','auto','auto']},{id:1,name:'双列',desc:'flexBasis: 50%',bases:['50%','50%','50%','50%','50%']},{id:2,name:'黄金比例',desc:'大卡 flexBasis: 40%,小卡 30%',bases:['40%','30%','30%','40%','60%']},{id:3,name:'全宽单列',desc:'flexBasis: 100%',bases:['100%','100%','100%','100%','100%']},]build(){Column(){// ── 页面标题 ──Row(){Text('数据仪表盘').fontSize(20).fontWeight(FontWeight.Bold).fontColor('#1A1A1A')Blank()Text('今日 09:00 更新').fontSize(12).fontColor('#AAAAAA')}.width('100%').padding({left:24,right:24,top:20,bottom:4})// ── 布局模式切换 ──Row({space:8}){Text('布局模式:').fontSize(13).fontColor('#666666')ForEach(this.layoutModes,(mode:LayoutModeParams)=>{Column({space:2}){Text(mode.name).fontSize(13).fontColor(this.currentMode===mode.id?'#0A59F7':'#666666').fontWeight(this.currentMode===mode.id?FontWeight.Bold:FontWeight.Normal)Text(mode.desc).fontSize(10).fontColor(this.currentMode===mode.id?'#4D87F7':'#AAAAAA')}.padding({left:12,right:12,top:6,bottom:6}).backgroundColor(this.currentMode===mode.id?'#EBF2FF':'#F5F5F5').border({width:1,color:this.currentMode===mode.id?'#0A59F7':'transparent',radius:8}).onClick(()=>{this.currentMode=mode.id})})}.width('100%').padding({left:24,right:24,top:4,bottom:16})Divider().color('#EEEEEE')// ── 卡片区域 ──Scroll(){Column(){// flexBasis 演示:Flex wrap 布局Flex({wrap:FlexWrap.Wrap,alignItems:ItemAlign.Stretch}){ForEach(this.cards,(card:DashCard,index:number)=>{this.buildDataCard(card,this.layoutModes[this.currentMode].bases[index])})}.width('100%').padding({left:16,right:16,top:16,bottom:16})// ── flexBasis 说明 ──this.buildExplainSection()}}.layoutWeight(1).scrollBar(BarState.Auto)}.width('100%').height('100%').backgroundColor('#F5F6F8')}// ── 数据卡片 ──@BuilderbuildDataCard(card:DashCard,basis:string){Column({space:8}){// 标题Text(card.title).fontSize(13).fontColor('rgba(255,255,255,0.8)').maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis})// 数值Row({space:4}){Text(card.value).fontSize(28).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')if(card.unit){Text(card.unit).fontSize(14).fontColor('rgba(255,255,255,0.7)').margin({top:8})}}// 趋势标签Row({space:4}){Text(card.trend>=0?'↑':'↓').fontSize(12).fontColor('#FFFFFF')Text(`${Math.abs(card.trend)}%`).fontSize(12).fontColor('#FFFFFF')Text(card.trend>=0?'环比上升':'环比下降').fontSize(11).fontColor('rgba(255,255,255,0.7)')}.padding({left:8,right:8,top:3,bottom:3}).backgroundColor('rgba(0,0,0,0.15)').borderRadius(12)}.flexBasis(basis)// 关键:从外部传入 flexBasis 值.flexGrow(1)// 配合 flexGrow,弹性填充剩余空间.padding(20).margin(8).backgroundColor(card.color).borderRadius(16).alignItems(HorizontalAlign.Start).shadow({radius:12,color:`${card.color}40`,offsetX:0,offsetY:4}).animation({duration:300,curve:Curve.EaseInOut})}// ── 说明区域 ──@BuilderbuildExplainSection(){Column({space:12}){Text('flexBasis 工作原理').fontSize(15).fontWeight(FontWeight.Bold).fontColor('#1A1A1A')Column({space:8}){this.buildExplainRow('flexBasis: auto','以 width/height 属性为基准(默认行为)')this.buildExplainRow('flexBasis: 50%','基准尺寸为父容器的 50%,两列等宽布局')this.buildExplainRow('flexBasis: 200','固定 200vp 作为基准,再根据 flexGrow 伸展')this.buildExplainRow('flexBasis vs width','Flex 容器内 flexBasis 优先级高于 width')}.padding(16).backgroundColor('#FFFFFF').borderRadius(10)Text('上方切换布局模式,观察不同 flexBasis 值对卡片排列的影响').fontSize(12).fontColor('#AAAAAA').margin({top:4})}.width('100%').padding({left:24,right:24,top:0,bottom:24}).alignItems(HorizontalAlign.Start)}@BuilderbuildExplainRow(term:string,desc:string){Row({space:8}){Text(term).fontSize(13).fontColor('#0A59F7').fontFamily('monospace').width(160)Text(desc).fontSize(13).fontColor('#555555').layoutWeight(1)}.width('100%').padding({top:6,bottom:6})}}

flexBasis、flexGrow、flexShrink 三者的关系

这三个属性经常配合使用,用一个简单的公式理解:

实际尺寸 = flexBasis(基准) + flexGrow × (剩余空间 / 总flexGrow值) - flexShrink × (超出空间 / 总flexShrink值)

在实际代码里,最常见的组合是:

// 等比例弹性卡片:每张卡片基准 50%,有剩余空间就平分.flexBasis('50%').flexGrow(1).flexShrink(1)// 固定宽度保底,有多余空间再扩展.flexBasis(200).flexGrow(1).flexShrink(0)// 不允许压缩到 200vp 以下

PC 端仪表盘的布局建议

PC 端屏幕宽,仪表盘卡片可以放 3-4 列。推荐用以下基准:

布局flexBasis 值适用场景
四列等宽25%数据指标密集型
三列等宽33.33%标准仪表盘
两列等宽50%数据内容丰富
主次布局60%+40%主图 + 辅助数据

小结

flexBasis是 Flex 弹性布局的"起点设定":先确定基准尺寸,再用flexGrow伸展、flexShrink收缩。三个属性合在一起,构成完整的 Flex 弹性尺寸控制体系。

在 PC 端仪表盘场景里,用不同的flexBasis值配合FlexWrap.Wrap换行,可以非常灵活地控制卡片的排列密度和比例关系。

http://www.zskr.cn/news/1514437.html

相关文章:

  • LabVIEW实战:用反馈节点和属性节点,5分钟打造一个带状态记忆的简易计数器UI
  • 部署了不会用?来学Claude Code 的 10 个“邪修”秘籍
  • 有限元方法在正曲率流形等距嵌入中的应用与实现
  • SteamShutdown终极指南:告别熬夜等待,让电脑自动关机的智能解决方案
  • 上海ECO棉床垫怎么挑?去了5家店说点大实话 - 深圳市民HLL
  • 鸿蒙原生应用实战(五):路由导航与工程优化 — 从开发到上线的完整流程
  • 基于ARM Cortex-M0+的WPR1516无线充电接收芯片:15W Qi标准方案解析与开发实战
  • S32K3 MCAL实战:手把手教你用EB tresos Studio配置160MHz系统时钟(从晶振到PLL)
  • Flutter Hero 动画与共享元素转场:从原理到跨页面动效的工程实践
  • 2026年泰州全屋定制工厂口碑观察:谁在坚守品质与交付? - 优质品牌商家
  • 从箱线图升级到小提琴图?先搞懂KDE这个‘坑’:数据分布可视化中的平滑与失真
  • 新人和数采GEO工具测评:AI赋能本地商家引流,值得中小企业
  • 2026年当前嘉兴优秀的门墙柜一体化定制平台综合解析与推荐 - 品牌鉴赏官2026
  • Agent 系列(19):Harness 完整体系——8 层防护框架全景
  • 摆脱论文困扰!盘点2026年人气爆表的的降AI率平台
  • Okbiye AI 写作:毕业论文一站式智能创作工具,抚平毕业生论文撰写全流程压力
  • 用三菱GXWorks2的SFC功能,手把手教你做个玩具分拣产线模拟程序(附完整源码)
  • 从高铁选座到密码加密:用Python解决8个意想不到的生活小问题
  • 2026年德力斯手套箱行业精选厂家分析:技术、服务与案例全景解读 - 优质品牌商家
  • 用三菱PLC GXWorks2的SFC功能,搞定玩具分拣产线编程(附完整程序下载)
  • 5分钟快速上手:Locale-Emulator终极指南,彻底解决日文游戏乱码问题
  • 2026年齿轮加工厂分布全解析:从华北到西南的产业格局与实力厂商对比 - 优质品牌商家
  • 终极yuzu模拟器指南:3小时从零到精通,免费畅玩Switch游戏
  • 【鸿蒙原生应用开发实战】第二篇:首页开发——宠物卡片+快捷入口+动态信息流
  • 2026年6月德州企业车拖车服务贴心推荐指南:如何构建高效的车辆应急保障体系 - 品牌鉴赏官2026
  • 2026年中济南地区值得信赖的氨基磺酸实力生产供应商深度解析 - 品牌鉴赏官2026
  • SpaceX 750 亿美元 IPO 估值达 1.77 万亿美元,马斯克距万亿身家仅一步之遥
  • 告别Windows思维:在EAIDK-610的Linux上用Vim和GDB调试你的第一个C++程序
  • OpenAI营销权一分为二,B2B老将Fleming上任,能否破局企业市场混战?
  • 2026年四川变压器回收公司服务能力对比:哪些企业值得关注? - 优质品牌商家