吸顶效果,即页面滚动时让某一区域(如分类导航栏)固定在顶部,随页面滚动贴在标题栏下方,类似 Android/iOS 原生设计中的 StickyHeader。 本文结合实际生产页面HomeExplorePage,深入解析 Harmon
先看结论
阅读导航
一、效果演示
二、布局结构整体布局采用 外层 Scroll + 内层 Tabs + 子列表 的嵌套结构,与业界通用方案一致:
三、四个关键属性(重点)要实现流畅的吸顶效果,必须同时满足以下四个条件,缺一不可。 关键① —— 外层滚动器:height='100%'
作用: height('100%') 表示 Scroll 的高度基准等于父容器,不对子内容做高度截断。子 Column 的总高度由内部所有子组件回推得到,当内容超出屏幕时自然产生滚动区域。 常见误区:
关键② —— Tabs 高度与 barHeight
关键②-a:height = calc(100% - avoidanceHeight)原理:
使用 calc(100% - avoidanceHeight) 后:
效果: Tabs 精确填满 Scroll.Column 减去上方 Banner 和 hint 后的剩余垂直空间,列表内容不会溢出屏幕。 关键②-b:barHeight('auto')作用: tabBar 的高度由 Builder 内容自动撑开,而非固定数值。 在 tabBarBuilder 中,Row 高度为 44(tabs 文字行)+ Divider(1),如果使用固定数值如 barHeight(48):
barHeight('auto') 让 HarmonyOS 根据 tabBarBuilder() 实际渲染出的高度来计算 tabBar 区域,保证与 Builder 内容精确匹配。 附加配置:
关键③ —— nestedScroll:父子滚动联动
核心作用: 决定父子两个滚动容器“谁先响应滚动”。 scrollForward: PARENT_FIRST(向下滚动 / 手指上滑):
scrollBackward: SELF_FIRST(向上滚动 / 手指下滑):
关键④ —— edgeEffect:吸顶边界处理
参数详解: EdgeEffect.None — 禁用弹性回弹
alwaysEnabled: true — 保持边缘滚动感知(关键) 这是最容易遗漏的参数,作用如下:
常见误区: 如果只写 .edgeEffect(EdgeEffect.None) 而不设置 alwaysEnabled: true,会出现"卡顿"现象——列表到顶后外层 Scroll 短暂不响应,然后突然抢走滚动权,导致 TabBar 在顶部抖动。 综合效果:
四、完整代码示例以下为抽取核心逻辑后的最小可运行示例,基于 Demo 页面 :
五、实战:HomeExplorePage 中的吸顶实现生产环境中的 与 Demo 逻辑完全一致,核心配置如下:
六、方案总结
核心心法: 吸顶的本质是 父子滚动器的嵌套联动 — 子列表到顶后让出滚动权给外层 Scroll,上滑时外层 Scroll 先滚回再交还滚动权给列表。四个关键属性缺一,联动链条即断裂。 |
2022-04-23
2023-04-23
2024-04-08
2024-11-15
2022-10-16