HarmonyOS鸿蒙Next中通过ListItemGroup、nestedScroll实现商城活动可折叠分组滚动效果
HarmonyOS鸿蒙Next中通过ListItemGroup、nestedScroll实现商城活动可折叠分组滚动效果

通过ListItemGroup、nestedScroll实现商城活动可折叠分组滚动效果
默认宣传封面
当上拉时候大导航吸顶
继续上拉小导航吸灯并且会随着拉上切换小导航
更多关于HarmonyOS鸿蒙Next中通过ListItemGroup、nestedScroll实现商城活动可折叠分组滚动效果的实战教程也可以访问 https://www.itying.com/category-93-b0.html
真不错
更多关于HarmonyOS鸿蒙Next中通过ListItemGroup、nestedScroll实现商城活动可折叠分组滚动效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
效果预览:

实现思路:
1、根据效果图颜色 先实现红、蓝、列表布局
2、给最外层加上Scroll实现嵌套滚动,最初上拉红色慢慢隐藏、绿色吸灯
3、给List增加ListItemGroup分组实现小导航吸顶效果
完整代码:
@Entry
@Component
struct Index {
@Builder GroupTitleBuilder(text: string) {
// 列表分组的头部组件,对应联系人分组A、B等位置的组件
Text(text)
.fontSize(20)
.backgroundColor('#fff1f3f5')
.width('100%')
.padding(5)
}
build() {
// 核心1⭐️:多层嵌套滚动
Scroll() {
Column() {
// 红色
Text().width('100%').height(100).backgroundColor(Color.Red)
// 蓝色
Text().width('100%').height(50).backgroundColor(Color.Blue)
// 列表
List() {
// 分组
ForEach('ABCDEF'.split(''), (title:string) => {
ListItemGroup({ header: this.GroupTitleBuilder(title) }) {
// 每个分组下面的内容(咱们这里每个分组内容一样)
ForEach('123456'.split(''), (item:string) => {
ListItem() {
Text(item).height(50).fontSize(30)
}
})
// 每个分组下面的内容(咱们这里每个分组内容一样)
}.divider({strokeWidth:2,color:Color.Red})
})
// 分组
}.sticky(StickyStyle.Header)
// 核心2⭐:上拉黄色慢慢消失、蓝色一直在 也就是减去蓝色高度
.height('calc(100% - 50vp)')
// 核心3⭐️:向前向后滚动模式 -> 实现与父组件的滚动联动
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST, // 上拉
scrollBackward: NestedScrollMode.SELF_FIRST // 下拉
// 不管父-SELF_ONLY、SELF_FIRST-到边缘管父、PARENT_FIRST-到边缘管子、PARALLEL-父子同时
// 详细 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V13/ts-appendix-enums-V13#nestedscrollmode10
})
}
}
}
}
在HarmonyOS Next中,使用ListItemGroup配合nestedScroll实现商城活动的可折叠分组滚动效果,是一个典型的复杂列表交互场景。以下是实现的核心思路和关键点:
1. 布局结构
建议采用Scroll嵌套List的方式,外层Scroll实现整体页面滚动,内层List使用ListItemGroup管理可折叠的活动分组。大导航栏可作为Scroll的兄弟节点,通过nestedScroll事件控制其吸顶。
2. 关键实现
ListItemGroup:用于管理每个活动分组,通过isExpanded属性控制折叠/展开状态。每个ListItemGroup的头部可放置小导航栏。nestedScroll:需要在外层Scroll上监听滚动事件。通过NestedScrollOnScroll事件获取滚动偏移量,以此计算并触发以下行为:- 当滚动到预设位置时,将大导航栏的布局位置固定(吸顶)。
- 继续滚动时,计算当前处于视窗主要区域的活动分组,并高亮对应的小导航项,同时可实现小导航栏的吸顶效果。
3. 状态联动
这是交互难点。需要建立滚动位置、当前活动分组索引、大/小导航栏状态之间的绑定关系。建议使用@State或@Link装饰器管理当前激活的分组索引,滚动事件中实时计算并更新该索引,从而驱动UI切换。
4. 性能优化
- 对于复杂活动列表,
List应使用if/else或LazyForEach进行按需渲染,避免一次性加载所有内容。 - 滚动事件计算应做防抖或节流优化,避免频繁触发UI更新。
示例代码框架示意:
@Entry
@Component
struct MallActivityPage {
private scrollController: ScrollController = new ScrollController();
@State currentGroupIndex: number = 0; // 当前激活分组索引
@State isBigNavSticky: boolean = false; // 大导航是否吸顶
build() {
Column() {
// 大导航栏
BigNavBar()
.opacity(this.isBigNavSticky ? 1 : 0) // 示例:通过透明度或位置控制显隐
Scroll(this.scrollController) {
// 活动列表区域
List() {
ForEach(this.activityGroups, (group) => {
ListItemGroup({ isExpanded: this.currentGroupIndex === group.index }) {
// 分组内容...
}
})
}
}
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST, // 父容器先滚动
onScroll: (scrollOffset: number) => {
// 计算逻辑:更新 this.isBigNavSticky 和 this.currentGroupIndex
}
})
}
}
}
总结:实现此效果的关键在于通过nestedScroll精确掌控滚动过程,并将滚动位置映射为ListItemGroup的折叠状态与导航栏的UI状态。需要精细计算滚动阈值,并确保状态变化流畅自然。


