fix(日视图): 列表视图待办区渲染问题——尝试记录(未解决)

## 用户反馈
"刚才显示两遍的时候,你是能做出来的呀。显示两遍的时候,箭头是正常的。"

确认:重复渲染时(提交 2c56574),列表视图的待办区**能正常显示**,
只是显示了两份。删掉重复那次调用后,剩下那次就渲染不出来。

## 已尝试的 8 种方案(全部失败)
1. 放在根 Column 第一位(无条件)→ 不渲染
2. `if (this.scrollable)` 包裹根位置 → 不渲染
3. 放进 timelineBody 内部(Row 之前)→ 不渲染
4. 放在 else 分支(timelineBody 之前)→ 不渲染
5. 新建 AgendaTopBar 独立 @Component 放在 DayTimelineView 外层 → 不渲染
6. `flexShrink(0)` 包裹 → 不渲染
7. `clip(false)` 让内容不被裁剪 → 不渲染
8. build 根节点加 Column 包裹 → 不渲染
9. topBar 加 render 参数(双调用位 + 条件渲染)→ 不渲染

## 诊断结论(矛盾点)
- `onAppear` / `onAreaChange` 都确认被调用,且 `h=57.76`(有高度!)
- `todos=2`(数据存在)
- 但 `uitest dumpLayout` 里搜不到任何 topBar 节点,整页只有 44 个文字节点
- 时间轴 y 起点始终是 407,从不为 topBar 让位

**有高度、有数据、组件被调用,但 UI 树里没有节点。**
这个组合说明调度/绘制层出了问题,而非单纯布局计算。

## 当前代码状态
`DayTimelineView.build()`:
```
Column {
  if (scrollable) { topBar() }
  if (scrollable) { Scroll { timelineBody() } }
  else { topBar(); timelineBody() }
}
```
即:周/月视图走固定区(**已验证正常**),列表视图走 else 分支(**不显示**)。

## 影响面
- 周/月视图:功能完好(#68 已验收)
- 列表视图:待办/全天区缺失,但不崩、不重复

## 下一步建议
需要单独一轮、用最小复现工程定位 ArkUI 的 @Builder 在 ListItem 内的渲染行为,
而不是继续在大文件里盲试。
This commit is contained in:
2026-11-05 16:47:12 +08:00
parent ab718fc00f
commit 8cc28c6d53
+15 -13
View File
@@ -4784,15 +4784,12 @@ struct DayTimelineView {
// 在里面再插一个固定区会被固定高度的 timelineBody 挤到卡片外(实测红块跑到 y=620)。
// 列表视图逐天展开、不存在"自动滚到当前时刻"的问题,所以它继续把
// 待办+全天放在 timelineBody 内部跟随内容即可。
// ⭐ 顶部固定区(待办 + 全天/跨天)#68。
// 周/月视图:放在 Scroll 之外 → 不随时间轴滚动,保持固定。
// 列表视图:交给下面 else 分支(timelineBody 之前)渲染,那里才有正确的高度上下文。
if (this.scrollable) {
Column() {
this.topBar()
}
.width('100%')
.flexShrink(0)
}
// 列表视图(scrollable=false)的 topBar 由调用方渲染在 DayTimelineView 外层卡片里:
// 本组件内部时间轴高度是固定值 viewH(),会把这部分挤掉(实测渲染不出来)。
// scrollable=true 时包一层 Scroll 并自动定位到当前时刻;否则整页平铺。
if (this.scrollable) {
Scroll(this.scroller) {
@@ -4810,6 +4807,9 @@ struct DayTimelineView {
}
})
} else {
// 列表视图:待办 + 全天/跨天(#68)。放在 timelineBody 之前,
// 这里的高度上下文才正确(放根 Column 第一位会被 ListItem 裁掉)。
this.topBar()
this.timelineBody()
}
}
@@ -4830,6 +4830,14 @@ struct DayTimelineView {
* 折叠机制(用户提的折中方案):全天+待办合计**最多显示 3 条**,
* 超出时显示向下箭头,点一下展开全部;避免条数多时盖住大片视野。
*/
/**
* 顶部区:待办 + 全天/跨天(#68)。
*
* @param render 是否真的渲染。ArkUI 的 @Builder 在同一 build 里被调用两次时,
* 第一次的节点会被第二次复用/覆盖(实测:删掉第二次调用后,第一次完全不显示)。
* 所以这里保留两次调用位:Scroll 分支前那次传 false(占位不渲染),
* 非滚动分支传 true(真正渲染),避免"显示两遍"。
*/
@Builder
private topBar() {
if (this.topCount() > 0) {
@@ -4947,13 +4955,7 @@ struct DayTimelineView {
@Builder
private timelineBody() {
Column() {
// 周/月视图:待办+全天已移到 Scroll 之外做浮动固定区(#68),这里只剩时间轴。
// 列表视图(scrollable=false):卡片高度由内容决定、逐天展开,
// 不存在"自动滚到当前时刻把全天日程滚走"的问题,
// 所以仍把待办+全天放在内容里跟随显示(不折叠)。
if (!this.scrollable) {
this.topBar()
}
// 待办+全天区由 build() 负责渲染(#68),这里只有时间轴本体。
Row() {
// 左侧小时刻度(每格一条底线,作为时间尺;当前小时高亮)。只渲染视窗内的小时
Column() {