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

HarmonyOS6 ArkTS ListItemGroup设置Header/Footer

文章目录

    • 一、核心概念与配置方式
      • 1. 两种配置方式对比
      • 2. 核心属性优先级
      • 3. 接口说明
    • 二、Header/Footer核心配置与API
      • 1. 传统配置(header/footer)
      • 2. 新版配置(headerComponent/footerComponent)
      • 3. 构建器参数封装
    • 三、完整实现示例
      • 1. 代码实现
    • 四、功能效果与核心逻辑说明
      • 1. 基础效果
      • 2. 动态更新逻辑
      • 3. 组件层级约束
      • 4. 新版配置(ComponentContent)约束
      • 5. 样式与布局约束
      • 6. 动态更新约束
      • 7. 吸顶/吸底联动约束
    • 总结

一、核心概念与配置方式

1. 两种配置方式对比

ListItemGroup提供传统Builder新版ComponentContent两种Header/Footer配置方式,二者可单独使用,新版方式优先级更高且支持动态更新,具体对比如下:

配置方式对应属性基于类型核心特性API版本动态更新
传统方式header/footerCustomBuilder静态配置,简单易用9+不支持
新版方式headerComponent/footerComponentComponentContent动态更新,灵活扩展13+支持

2. 核心属性优先级

当同时配置传统header/footer和新版headerComponent/footerComponent时,新版属性优先级更高,系统会优先渲染headerComponent/footerComponent对应的内容,传统属性会被忽略。

3. 接口说明

  • ComponentContent:API 13新增的组件内容封装类,支持传入构建器、参数并实现动态更新,是新版Header/Footer的核心载体;
  • wrapBuilder:将自定义@Builder构建器转换为ComponentContent可识别的构建器类型,实现Builder与ComponentContent的适配;
  • IDataSource:LazyForEach的数据源接口,通过notifyDataChange实现数据更新后UI的联动刷新。

二、Header/Footer核心配置与API

1. 传统配置(header/footer)

语法

ListItemGroup({header:自定义Builder构建器,footer:自定义Builder构建器})

2. 新版配置(headerComponent/footerComponent)

核心语法

// 初始化ComponentContentnewComponentContent(this.getUIContext(),wrapBuilder(自定义Builder),构建器参数)// ListItemGroup配置ListItemGroup({headerComponent:初始化后的ComponentContent实例,footerComponent:初始化后的ComponentContent实例})

更新方法

// 动态更新ComponentContent的参数componentContent实例?.update(新的构建器参数)

3. 构建器参数封装

通过自定义类封装Builder的入参,实现参数的统一管理和动态传递,语法示例:

// 头部参数封装classHeadBuilderParams{text:string|Resource;constructor(text:string|Resource){this.text=text;}}

三、完整实现示例

1. 代码实现

import{ComponentContent}from'@kit.ArkUI';import{TimeTable,ProjectsDataSource,TimeTableDataSource}from'./ListDataSource';// 头部构建器参数封装:分组标题classHeadBuilderParams{text:string|Resource;constructor(text:string|Resource){this.text=text;}}// 尾部构建器参数封装:课程数量统计classFootBuilderParams{num:number|Resource;constructor(num:number|Resource){this.num=num;}}// 头部自定义构建器@BuilderfunctionitemHead(params:HeadBuilderParams){Text(params.text).fontSize(20).height('48vp').width('100%').padding(10).backgroundColor($r('sys.color.background_tertiary'))}// 尾部自定义构建器@BuilderfunctionitemFoot(params:FootBuilderParams){Text('共'+params.num.toString()+'节课').fontSize(20).height('48vp').width('100%').padding(10).backgroundColor($r('sys.color.background_tertiary'))}// 自定义分组组件:封装ListItemGroup与Header/Footer@Componentstruct MyItemGroup{item:TimeTable={title:'',projects:[]};header?:ComponentContent<HeadBuilderParams>=undefined;footer?:ComponentContent<FootBuilderParams>=undefined;headerParam=newHeadBuilderParams(this.item.title);footerParam=newFootBuilderParams(this.item.projects.length);itemArr:ProjectsDataSource=newProjectsDataSource([]);// 初始化ComponentContentaboutToAppear():void{this.header=newComponentContent(this.getUIContext(),wrapBuilder(itemHead),this.headerParam);this.footer=newComponentContent(this.getUIContext(),wrapBuilder(itemFoot),this.footerParam);this.itemArr=newProjectsDataSource(this.item.projects);}// 动态更新头部参数并返回实例GetHeader(){this.header?.update(newHeadBuilderParams(this.item.title));returnthis.header;}// 动态更新尾部参数并返回实例GetFooter(){this.footer?.update(newFootBuilderParams(this.item.projects.length));returnthis.footer;}build(){// 核心:配置headerComponent/footerComponentListItemGroup({headerComponent:this.GetHeader(),footerComponent:this.GetFooter()}){// 懒加载分组子项LazyForEach(this.itemArr,(project:string)=>{ListItem(){Text(project).width('100%').height(100).fontSize(20).textAlign(TextAlign.Center)}},(item:string)=>item)}.divider({strokeWidth:1,color:Color.Blue})// 子项分割线}}// 主页面组件@Entry@Componentstruct Index{itemGroupArray:TimeTableDataSource=newTimeTableDataSource([]);// 初始化分组数据源aboutToAppear():void{lettimeTable:TimeTable[]=[{title:'星期一',projects:['语文','数学','英语']},{title:'星期二',projects:['物理','化学','生物']},{title:'星期三',projects:['历史','地理','政治','体育']},{title:'星期四',projects:['美术','音乐']}];this.itemGroupArray=newTimeTableDataSource(timeTable);}build(){Column(){// 数据更新按钮:修改第一个分组的Header/Footer内容Button('update').width(100).height(50).onClick(()=>{this.itemGroupArray.change1stItem({title:'更新后的星期一',projects:['语文','物理','历史','美术']});})// List容器:开启吸顶/吸底List({space:20}){LazyForEach(this.itemGroupArray,(item:TimeTable)=>{MyItemGroup({item:item})},(item:TimeTable)=>item.title)// 依赖title作为键值实现UI刷新}.layoutWeight(1).sticky(StickyStyle.Header|StickyStyle.Footer)// Header吸顶、Footer吸底.scrollBar(BarState.Off)}.backgroundColor($r('sys.color.background_primary'))}}

运行效果如图:

滑动的时候可以观察到:

四、功能效果与核心逻辑说明

1. 基础效果

  • Header:展示每个分组的标题(如“星期一”“星期二”),使用系统次级背景色,固定高度48vp,宽度充满父容器;
  • Footer:展示每个分组的课程数量统计(如“共3节课”),与Header样式统一,实现视觉一致性;
  • 分割线:通过divider属性为分组内子项添加蓝色1px分割线,提升列表层次感;
  • 吸顶/吸底:通过List的sticky属性实现Header吸顶、Footer吸底,滚动时保持分组标识可见。

2. 动态更新逻辑

  1. 点击update按钮,调用数据源的change1stItem方法修改第一个分组的标题和课程列表;
  2. 数据源通过notifyDataChange(0)通知UI层数据更新;
  3. LazyForEach根据item.title作为键值,识别到数据变化后刷新对应的MyItemGroup组件;
  4. MyItemGroupGetHeader/GetFooter方法调用ComponentContentupdate方法,传递新的参数;
  5. Header/Footer根据新参数重新渲染,实现动态更新标题和统计数据

3. 组件层级约束

  • ListItemGroup必须作为List的直接子组件,不可嵌套在Column、Row等其他容器中,否则Header/Footer配置失效;
  • Header/Footer的宽度默认与List保持一致,手动设置宽度可能导致布局错乱,建议使用width('100%')

4. 新版配置(ComponentContent)约束

  1. 同一个ComponentContent实例不推荐同时给不同的ListItemGroup使用,否则会导致显示错乱、更新异常;
  2. 初始化ComponentContent时必须传入当前组件的UI上下文this.getUIContext()),否则无法正常渲染;
  3. wrapBuilder函数仅用于转换@Builder构建器,不可直接传入组件实例。

5. 样式与布局约束

  1. 当List的listDirectionAxis.Vertical(默认)时,ListItemGroup的height属性不生效,高度由Header高度+Footer高度+所有子项高度自动计算;
  2. Header/Footer与子项之间无默认间距,如需调整可在Builder中通过padding/margin实现,space属性仅作用于子项之间;
  3. 建议为Header/Footer设置固定高度,避免动态高度导致的滚动卡顿和布局偏移。

6. 动态更新约束

  1. 使用LazyForEach时,必须指定唯一的键值(如示例中的item.title),否则数据更新后UI无法正常刷新;
  2. 数据源修改后,必须调用notifyDataChange方法通知UI层,否则ComponentContentupdate方法无效;
  3. 新版配置仅支持API 13及以上版本,低版本需使用传统header/footer配置。

7. 吸顶/吸底联动约束

  • Header/Footer的吸顶/吸底效果由List的sticky属性控制,ListItemGroup自身无独立配置;
  • 吸顶/吸底的Header/Footer会覆盖List的顶部/底部区域,建议避免在Header/Footer中添加可点击的高频操作按钮,防止遮挡。

总结

  1. ListItemGroup的Header/Footer有传统Builder新版ComponentContent两种配置方式,新版支持动态更新且优先级更高;
  2. 新版配置的核心是ComponentContent类,通过wrapBuilder实现与自定义Builder的适配,通过update方法实现动态参数修改;
  3. 动态更新需配合IDataSource和LazyForEach,通过数据通知唯一键值实现UI与数据的联动;
  4. Header/Footer可与吸顶/吸底、分割线、卡片样式等功能结合,实现多样化的分组列表效果;
  5. 开发时需遵循组件层级、版本兼容、实例复用等约束,保证布局稳定和性能优化。

如果这篇文章对你有帮助,欢迎点赞、收藏、关注,你的支持是持续创作的动力!

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

相关文章:

  • 别再买错千元投影! 哈趣Q1Pro藏看越级体验
  • 突破Web墨卡托限制:Mapbox-gl.js v2.15.0 自定义坐标系扩展实战
  • 避坑指南:PyTorch模型保存时选torch.save还是state_dict?5个实际项目经验总结
  • 低噪声放大器设计中的常见误区与优化技巧:如何避免噪声系数飙升
  • OpCore-Simplify:智能重构黑苹果配置流程的效率革命
  • Unity微信小游戏打包后,如何用七牛云CDN加速资源加载(附完整配置流程与避坑点)
  • Claude Code 源码泄漏:想研究的赶紧 fork,可能随时消失
  • Win10下QTTabBar安装全攻略:解决.NET 3.5报错0x80240438的终极方案
  • IPXWrapper焕新攻略:让经典游戏在Windows 11完美联机
  • CanFestival主站PDO配置避坑指南:以Kinco FD伺服的速度/位置模式控制为例
  • HarmonyOS6 ArkTS ListItemGroup设置多列布局
  • Sunshine:5步打造你的专属游戏串流服务器,随时随地畅玩PC大作
  • Lingbot 模型与 Dify 集成:构建无需编码的深度图生成 AI 应用
  • MoveIt!与Gazebo联调实战:手把手教你配置controllers_gazebo.yaml(附常见报错修复)
  • 从仿真到实车:解析Fast-LIO2定位中坐标系缺失的排查与修复
  • AI绘画新手指南:用FLUX.1和SDXL风格,轻松生成高质量图片
  • 程序员转型AI大模型全攻略:告别焦虑,抢占时代红利
  • Qwen3.5-2B轻量化部署:单卡3090上同时运行3个实例的资源分配方案
  • JavaScript 开发 - Object 的 hasOwn 方法
  • 3步构建稳定黑苹果:给硬件爱好者的OpenCore智能配置方案
  • 基于SpringBoot集成乙巳马年皇城大门春联生成终端W:打造企业级文化应用
  • 终极文件传输服务器SFTPGo:一站式解决企业级文件管理难题
  • 华为2288H V5服务器CentOS 7.5安装全记录:从BIOS密码到图形界面/最小化安装选择
  • 花卉智能分类实战:从数据预处理到模型部署
  • Qwen3智能字幕系统在网络安全领域的应用:音视频内容审计
  • Pixel Aurora Engine算力优化部署:混合精度推理降低推理延迟37%
  • Android 11+ 开发避坑:TextToSpeech报错‘speak failed: not bound to TTS engine’的完整排查与修复指南
  • UDOP-large文档理解模型实战:5步完成英文发票信息提取
  • 春联生成模型-中文-base实测:在Jetson Orin NX边缘设备上实时生成性能报告
  • 2026实测|6款好用的PPT生成工具,AI博主私藏,告别熬夜排版 - 品牌测评鉴赏家