Harmonyos pc实战之ArkUI 组件详解
文章目录
- 前言
- Column 的主轴和交叉轴
- PC端新闻阅读页:Column 的实战用法
- space 和 margin 的区别
- layoutWeight 是 Column 里的"弹性分配"
- 写在最后
前言
Column 是 ArkUI 里用得最多的布局容器之一,但很多人对它的理解就停在"子组件从上往下排列"这句话上。这当然没错,但 Column 真正的价值在于它的对齐控制、间距管理、以及和 Row 嵌套时产生的灵活性。
拿 PC 端新闻阅读列表来说,侧边栏导航、内容卡片列表、底部分页栏,每一层都是 Column 的应用,理解了 Column 才能把这种多层结构搭稳。
Column 的主轴和交叉轴
Column 的主轴是垂直方向(Y 轴),子组件按声明顺序从上往下排。交叉轴是水平方向(X 轴),控制子组件在水平方向的对齐。
justifyContent控制主轴(垂直)对齐:
Column(){Text('标题')Text('内容')}.height('100%').justifyContent(FlexAlign.SpaceBetween)// 顶部一个、底部一个alignItems控制交叉轴(水平)对齐:
Column(){Text('这行文字')Button('按钮')}.alignItems(HorizontalAlign.Start)// 左对齐.alignItems(HorizontalAlign.Center)// 居中(默认).alignItems(HorizontalAlign.End)// 右对齐PC端新闻阅读页:Column 的实战用法
完整示例:PcNewsListPage.ets
import{router}from'@kit.ArkUI'interfaceNewsItem{id:numbertitle:stringsource:stringtime:stringcategory:stringemoji:stringisTop:booleanreadCount:number}@Entry@Componentstruct PcNewsListPage{@StateactiveCategory:string='全部'@StatenewsList:NewsItem[]=[{id:1,title:'HarmonyOS NEXT 正式发布,全面进入鸿蒙时代',source:'华为官方',time:'10分钟前',category:'科技',emoji:'📱',isTop:true,readCount:12600},{id:2,title:'鸿蒙生态应用突破十万,覆盖主流场景',source:'鸿蒙生态',time:'30分钟前',category:'科技',emoji:'🌐',isTop:false,readCount:8900},{id:3,title:'ArkUI 4.0 新特性解读:动效系统全面升级',source:'开发者社区',time:'1小时前',category:'开发',emoji:'💻',isTop:false,readCount:5600},{id:4,title:'鸿蒙 PC 端适配指南:窗口管理与响应式布局',source:'技术博客',time:'2小时前',category:'开发',emoji:'🖥️',isTop:false,readCount:4200},{id:5,title:'智能家居新纪元:鸿蒙设备互联实战',source:'极客之家',time:'3小时前',category:'产品',emoji:'🏠',isTop:false,readCount:3100},{id:6,title:'国产操作系统的未来:鸿蒙 vs 其他竞争者',source:'科技评论',time:'5小时前',category:'产品',emoji:'🔮',isTop:false,readCount:9800},]privatecategories:string[]=['全部','科技','开发','产品']privategetFilteredNews():NewsItem[]{constlist=this.newsList??[]if(this.activeCategory==='全部')returnlistreturnlist.filter((n:NewsItem)=>n.category===this.activeCategory)}build(){Row(){// ── 左侧侧边栏 ──Column({space:0}){// Logo区Row({space:10}){Text('📰').fontSize(22)Text('鸿蒙资讯').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#111827')}.width('100%').padding({left:16,right:16,top:20,bottom:20}).border({width:{bottom:1},color:'#F3F4F6'})// 分类导航Column({space:4}){ForEach(this.categories,(cat:string)=>{Row({space:10}){Text(['全部','科技','开发','产品'].indexOf(cat)>=0?['🔷','💻','⚙️','📦'][['全部','科技','开发','产品'].indexOf(cat)]:'•').fontSize(14)Text(cat).fontSize(14).fontColor(this.activeCategory===cat?'#3B82F6':'#374151').fontWeight(this.activeCategory===cat?FontWeight.Medium:FontWeight.Normal)}.width('100%').padding({left:12,right:12,top:10,bottom:10}).borderRadius(8).backgroundColor(this.activeCategory===cat?'#EFF6FF':Color.Transparent).onClick(()=>this.activeCategory=cat)})}.padding({left:12,right:12,top:12}).layoutWeight(1)// 底部用户信息Row({space:10}){Stack(){Circle({width:32,height:32}).fill('#3B82F6')Text('U').fontSize(14).fontColor(Color.White).fontWeight(FontWeight.Bold)}Column({space:2}){Text('开发者').fontSize(13).fontColor('#111827').fontWeight(FontWeight.Medium)Text('已读 42 篇').fontSize(11).fontColor('#9CA3AF')}.alignItems(HorizontalAlign.Start)}.width('100%').padding({left:16,right:16,top:12,bottom:20}).border({width:{top:1},color:'#F3F4F6'})}.width(200).height('100%').backgroundColor(Color.White).border({width:{right:1},color:'#F3F4F6'})// ── 右侧内容区 ──Column(){// 顶部筛选栏Row(){Text(this.activeCategory==='全部'?'全部资讯':`${this.activeCategory}频道`).fontSize(18).fontWeight(FontWeight.Bold).fontColor('#111827')Blank()Text(`共${this.getFilteredNews().length}篇`).fontSize(13).fontColor('#9CA3AF')}.width('100%').padding({left:24,right:24,top:20,bottom:16})// 新闻列表Scroll(){Column({space:0}){ForEach(this.getFilteredNews(),(news:NewsItem)=>{Row({space:14}){// 图标Stack(){Circle({width:48,height:48}).fill('#F3F4F6')Text(news.emoji).fontSize(22)}.width(48).height(48).borderRadius(8)// 信息 ColumnColumn({space:6}){// 标题行Row({space:8}){if(news.isTop){Text('置顶').fontSize(10).fontColor('#EF4444').backgroundColor('#FEF2F2').borderRadius(4).padding({left:5,right:5,top:2,bottom:2})}Text(news.title).fontSize(14).fontColor('#111827').fontWeight(FontWeight.Medium).layoutWeight(1).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis})}// 元信息行Row({space:12}){Text(news.source).fontSize(12).fontColor('#6B7280')Text(news.time).fontSize(12).fontColor('#9CA3AF')Blank()Text(`👁${news.readCount>999?(news.readCount/1000).toFixed(1)+'k':news.readCount}`).fontSize(11).fontColor('#9CA3AF')}}.layoutWeight(1).alignItems(HorizontalAlign.Start)}.width('100%').padding({left:20,right:20,top:14,bottom:14}).border({width:{bottom:1},color:'#F9FAFB'}).backgroundColor(Color.White)})}}.layoutWeight(1).scrollBar(BarState.Off)}.layoutWeight(1).height('100%').backgroundColor('#F9FAFB')}.width('100%').height('100%')}}space 和 margin 的区别
Column 的space参数给所有相邻子项之间加统一间距,不影响首项顶部和末项底部。适合子项数量固定、间距统一的场景。
margin是给单个组件设置外边距,更灵活但也更繁琐——每个子组件都要单独写。
经验上:子项之间距离一致就用space,需要某个子项特殊间距就用margin。两者也可以混用。
layoutWeight 是 Column 里的"弹性分配"
Column 里的layoutWeight和 Flex 里的flexGrow效果类似:子组件按权重比例分配主轴(垂直)的剩余高度。
Column(){Text('固定高度标题').height(60)// 占 60vpContent().layoutWeight(1)// 占剩余全部Footer().height(64)// 占 64vp}.height('100%')这是 PC 端固定顶部 + 弹性内容 + 固定底部最常见的结构写法。
写在最后
Column 的justifyContent控制垂直分布,alignItems控制水平对齐,space统一间距,layoutWeight弹性分配高度——这四个属性搭配用好,PC 端大部分页面骨架都能建出来。
