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

HarmonyOS 实战教程(四):首页布局实现 —— Swiper 轮播、Grid 网格与组件化 —— 以「柚兔自测量表」为例

一、首页整体结构

MeCharts 首页HomeView承载了所有量表入口,整体结构为:顶部导航栏 + 可滚动内容区(轮播图 + 分类网格)。

@Preview@ComponentV2exportstruct HomeView{@LocalglobalInfoModel:GlobalInfoModel=AppStorage.get('GlobalInfoModel')||newGlobalInfoModel()privatepageContext:PageContext=AppStorage.get('pageContext')asPageContext;@LocalimgHeight:number=190@LocalimgWidth:number=264@LocalimgList:Resource[]=newArray(3).fill('').map((item:string,index)=>{return$r(`app.media.banner_0${index+1}`)})privateasdList:AbcModel[]=[newAbcModel($r('app.media.ic_item_abc'),'ABC量表','(自闭症行为评定量表)',1),newAbcModel($r('app.media.ic_item_cars'),'CARS量表','(儿童期孤独症评定量表)',2),newAbcModel($r('app.media.ic_item_move'),'多动症量表','(多动症诊断标准量表)',3),]privatecareerList:AbcModel[]=[newAbcModel($r('app.media.ic_item_mbti'),'MBTI测试','(MBTI职业性格测试完整版)',1),]privateemotionList:AbcModel[]=[newAbcModel($r('app.media.ic_item_depress'),'SDS量表','(抑郁自评量表)',1),newAbcModel($r('app.media.ic_item_anxious'),'SAS量表','(焦虑症自评量表)',2),newAbcModel($r('app.media.ic_item_relationship'),'ECR量表','(亲密关系经历量表)',3),]build(){Column(){this.buildTopBar();this.buildContentView();}.height('100%').width('100%').backgroundColor($r('app.color.color_background'))}}

1.1 数据模型设计

所有量表入口使用统一的AbcModel数据模型:

@ObservedexportclassAbcModel{img:Resource|undefined=undefinedtitle:string=''subTitle:string=''id:number=0score?:string=''type?:number=0constructor(img:Resource,title?:string,subTitle?:string,id?:number,score?:string,type?:number){// 构造函数赋值...}}

@Observed装饰器使该类的实例可被 ArkUI 框架观测,当属性变化时自动触发 UI 刷新。这在历史记录页面中更新分数显示时非常关键。

二、Swiper 轮播组件

2.1 基本使用

首页顶部使用UISwiper(AGConnect 提供的增强轮播组件)展示推荐量表:

UISwiper({imgWidth:this.imgWidth,imgHeight:this.imgHeight,imgList:this.imgList,isLoop:true,isCovered:false,onImageClick:(index:number)=>{if(index===0){this.pageContext.openPage({param:{title:'MBTI测试'}asResultParams,routerName:'MbtiListPage',},true);}elseif(index===1){this.pageContext.openPage({param:{title:'ABC量表'}asResultParams,routerName:'AbcListPage',},true);}elseif(index===2){this.pageContext.openPage({param:{title:'SAS量表',type:FormType.TYPE_SDS}asResultParams,routerName:'MoveListPage',},true);}}})

轮播图的点击事件通过onImageClick回调处理,根据索引跳转到不同量表页面。

2.2 原生 Swiper 的使用方式

如果使用原生 Swiper 组件,基础用法如下:

Swiper(){ForEach(this.imgList,(img:Resource)=>{Image(img).width(this.imgWidth).height(this.imgHeight).borderRadius(12).onClick(()=>{// 点击跳转逻辑})})}.autoPlay(true).interval(3000).indicator(true).loop(true).cachedCount(2)

原生 Swiper 的关键属性:

属性说明
autoPlay是否自动播放
interval自动播放间隔(ms)
indicator是否显示导航指示器
loop是否循环播放
cachedCount预缓存页面数

三、Grid 网格布局

3.1 分类网格实现

首页使用 Grid 布局展示三大分类的量表入口:

@BuilderbuildAbc(){// 分类标题Row({space:10}){Text().width(3).height(15).backgroundColor($r('app.color.color_default'));Text('自闭症相关').fontWeight(FontWeight.Bold).fontSize(16)}.margin({left:12})// 量表网格Grid(){ForEach(this.asdList,(asd:AbcModel,index)=>{GridItem(){Column({space:8}){Row({space:8}){Image(asd.img).width(24);Text(asd.title).fontWeight(FontWeight.Medium);};Text(asd.subTitle).fontSize(12);}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).borderRadius(15).width('100%').height('100%').backgroundColor($r('app.color.color_card'))}.onClick(()=>{// 跳转到对应量表页面})})}.padding(12).columnsTemplate('1fr 1fr')// 两列等宽.rowsTemplate('1fr 1fr')// 两行等高.columnsGap(10).rowsGap(10).width('100%').height(160)}

3.2 Grid 核心属性

columnsTemplate / rowsTemplate是 Grid 最核心的属性,定义了网格的行列结构:

.columnsTemplate('1fr 1fr')// 两列,每列等宽.rowsTemplate('1fr 1fr')// 两行,每行等高

fr是分数单位,1fr 1fr表示两列各占 1/2。更复杂的布局如:

.columnsTemplate('1fr 2fr 1fr')// 三列,中间列是两侧的两倍宽.rowsTemplate('auto auto')// 两行,高度由内容决定

columnsGap / rowsGap控制行列间距:

.columnsGap(10)// 列间距 10vp.rowsGap(10)// 行间距 10vp

3.3 不同分类的布局差异

MeCharts 根据量表数量灵活调整布局:

分类量表数量布局方式高度
自闭症相关3个2列×2行160
职业性格相关1个2列×1行80
情绪相关3个2列×2行160

职业性格分类只有一个量表,使用单行布局;其他分类使用 2×2 网格,空位自然留白。

四、TopBar 通用顶部导航栏

4.1 组件设计

TopBar 是全应用复用率最高的组件,支持标题、返回按钮和右侧自定义内容:

@ComponentV2exportstruct TopBar{privateglobalInfoModel:GlobalInfoModel=AppStorage.get('GlobalInfoModel')||newGlobalInfoModel();@Paramtitle:string=''@ParamshowBackButton:boolean=true@ParambgColor:ResourceColor=$r('app.color.color_default')@ParamtitleColor:ResourceColor=Color.White@ParambarHeight:number=80@ParamstatusBarHeight:number=this.globalInfoModel.statusBarHeight@EventonBack?:()=>void|boolean@BuilderParamrightContent?:()=>voidhandleBack(){if(this.onBack){constresult=this.onBack()if(result===false){return// 返回 false 可阻止默认行为}}}build(){RelativeContainer(){if(this.showBackButton){Image($r('app.media.ic_back')).width(20).height(20).id('backBtn').alignRules({left:{anchor:'__container__',align:HorizontalAlign.Start},center:{anchor:'__container__',align:VerticalAlign.Bottom}}).onClick(()=>{this.handleBack()})}Text(this.title).fontSize(18).fontWeight(FontWeight.Bold).fontColor(this.titleColor).id('title').alignRules({center:{anchor:'__container__',align:VerticalAlign.Bottom},middle:{anchor:'__container__',align:HorizontalAlign.Center}})if(this.rightContent){Row(){this.rightContent()}.id('rightContent').alignRules({right:{anchor:'__container__',align:HorizontalAlign.End},center:{anchor:'__container__',align:VerticalAlign.Bottom}})}}.width('100%').height(this.barHeight).backgroundColor(this.bgColor).padding({top:this.statusBarHeight,bottom:20,left:12,right:12})}}

4.2 RelativeContainer 相对布局

TopBar 使用RelativeContainer实现左右中三栏布局,这是 HarmonyOS 提供的相对定位容器:

  • 返回按钮:锚定容器左侧 + 垂直居中
  • 标题:锚定容器水平居中 + 垂直居中
  • 右侧内容:锚定容器右侧 + 垂直居中

相比 Flex 布局,RelativeContainer 在处理"左右对齐 + 中间居中"的场景时更简洁。

4.3 使用示例

首页使用 TopBar(无返回按钮 + 自定义右侧):

TopBar({title:'自测量表',showBackButton:false,rightContent:()=>{this.buildRightContent()},})

子页面使用 TopBar(有返回按钮):

TopBar({title:this.title,onBack:()=>{this.pageContext.popPage(true)}})

五、@ComponentV2 与 @Component 的选择

MeCharts 中两种组件声明方式并存:

  • @ComponentV2:新版本装饰器,支持@Param@Event@Local@Monitor等,类型安全更好
  • @Component:经典版本装饰器,支持@Prop@Link@State
特性@Component@ComponentV2
状态装饰器@State, @Prop, @Link@Local, @Param, @Event
状态观测基于代理基于拦截器,性能更优
参数传递构造函数传入@Param 声明式
事件回调箭头函数@Event 装饰器
监听变化@Watch@Monitor

新项目推荐优先使用@ComponentV2

六、小结

本篇讲解了首页的 Swiper 轮播、Grid 网格布局和 TopBar 通用组件的设计实现。通过组件化封装和统一数据模型,首页的代码结构清晰、复用性强。下一篇将深入量表答题页面的实现,讲解自定义 Radio 组件与表单交互。

http://www.jsqmd.com/news/1263930/

相关文章:

  • huststore同步机制深度剖析:数据一致性与高吞吐量的平衡之道
  • DeepSeek V4 API成本优化:缓存策略与批量处理的工程实践
  • Type Theme博客文章撰写指南:Markdown语法与特色功能使用技巧
  • 2026 年至今,陕县热门的塑料光亮剂生产厂家有哪些,旧塑料喷一喷,居然能新得像刚出厂?这玩意儿到底藏了啥玄机?-稳定嘉 - 鉴选官
  • oneAPI Math Library (oneMath)扩展开发:如何添加自定义数学函数后端
  • 解决Embark.vim常见问题:真彩色显示与终端兼容性完全指南
  • 使命召唤18先锋学习版安装教程:从环境准备到故障排查
  • 旧衣回收按斤算吗?爱宝拉高价上门回收真香揭秘 - 快递物流资讯
  • 从Java后端到AI应用开发:33岁转型踩坑8年终悟,2026年收藏这3类人慎重转行!
  • 深入解析TI C2000 F2807x:实时控制MCU架构、外设与电机控制实战
  • huststore API完全指南:从基础操作到高级功能的全面解析
  • 英雄联盟Akari助手:重新定义你的游戏准备体验
  • AI辅助教材写作:降低查重率的实战技巧与工具链
  • 扣子测试用例机器人落地踩坑实录:从零部署到日均生成286条高覆盖用例,我用这5步避开了83%的失败陷阱
  • 人民大学与蚂蚁集团联手,将AI推理模型扩展到一万亿参数
  • Jellium Desktop命令行自动补全:提升终端操作体验
  • 2026年AI大模型学习路径与核心技术解析
  • Adrenaline Todo应用教程:从零开始构建完整的GraphQL+React项目
  • 如何快速上手node-sonos:5分钟实现Sonos设备自动发现
  • eBPF网络监控新方案:LMP中tcpconnect工具的高级用法
  • 兰州下水道疏通专业速度服务上门快,下水道疏通那家好 管道疏通那家专业 - 园子一号
  • FDE实战一年:揭秘AI项目落地的“暗线”,小白程序员必备,助你成为业务翻译大师(收藏)
  • 打印机清零软件大揭秘!佳能MG3680/G4800/G1810/G1800/G2800/G3800/G2810全系列亲测有效5b00,5b02,5b04,1700,1702,1704,p07,亲测
  • Codex 长任务频繁中断怎么办?从上下文管理到 ChatGPT Pro 选择
  • 高精度ADC电源与PCB布局设计:从理论到实践的性能保障
  • Miden VM路线图深度解读:2024年即将发布的5大革命性功能
  • 腾讯云智能体开发平台构建知识库问答系统实战
  • 从ChatGPT到Coze:构建可视化AI工作流,实现复杂任务自动化
  • Inline-Execute-PE开发解析:BOF编写与CobaltStrike Aggressor脚本集成
  • Linux内核升级与NVIDIA驱动适配实战:从DKMS构建到AI辅助Bug排查