fix(harmony): 滚动列表上下边缘渐隐,替掉硬截断
用户(2026-09-17):「上下还是硬截断,不是 webui 那种渐变」。 WebUI 的做法是 `index.css` 给 `.overflow-y-auto` 加 `mask-image: linear-gradient(to bottom, transparent 0, #000 min(12px,10%), ...)`。 ArkUI 的对应物是滚动容器自带的 `fadingEdge(enabled, { fadingEdgeLength })` (API 14+,定义在 `ScrollableCommonMethod` 上 ⇒ List/Scroll/Grid/WaterFlow 都有), 它淡掉的是**渲染结果本身**,与背景无关。 **刻意不用** linearGradient + mask 手搓渐变色遮罩:那是拿背景色画一个 并不存在的"底色",在壁纸/玻璃主题下必然露馅(壁纸本身带颜色,遮罩层对不上)。 - 新增 `LIST_FADE_LENGTH = 12`(NavItems.ts):与 WebUI 的 `min(12px, 10%)` 同量级,也接近列表内边距(10vp)—— 静止时几乎看不出,滚动时才起作用。 - MainPage 的 5 个列表容器(收件箱/发件箱/授权/联系人卡片/联系人列表) 全部挂 `.fadingEdge(true, { fadingEdgeLength: LengthMetrics.vp(LIST_FADE_LENGTH) })`。 显式传长度而不是用默认 32vp:WebUI 那边踩过同一个坑 (「渐变用的过猛了,比如收件人候选那里」——固定像素用在高度不固定的容器上)。 判据(harmony-nav.test.mjs 新增一条):常量值、五个列表都挂、长度走 LengthMetrics.vp、禁止 linearGradient+mask 顶替;并做了变异自检 (删掉任一处 fadingEdge 必须判红,实测通过)。 实测(模拟器 1256×2760,密度 3.489): - 滚动后顶边被切断的卡片文字明显洗白(红色评分 5.5 vs 完整卡片 15.5); - 底边同样渐隐;截图 /tmp/harmony-fade-scroll.jpeg。 测试:199 passed / 0 failed。
This commit is contained in:
@ -111,6 +111,22 @@ export const NAV_CONTENT_ITEMS: NavItem[] = NAV_ITEMS.slice(0, NAV_CONTENT_COUNT
|
||||
/** 外壳入口(第 4 项「我的」)的路由目标 —— 与 WideSidebar 的 onSettings 同一地址 */
|
||||
export const NAV_SETTINGS_ROUTE: string = 'pages/SettingsPage';
|
||||
|
||||
/**
|
||||
* 滚动列表上下边缘的渐隐高度(vp)。
|
||||
*
|
||||
* 对应 WebUI `index.css` 的 `.overflow-y-auto { mask-image: linear-gradient(...) }`:
|
||||
* 滚动条本身是“一刀切”,卡片滑到边缘被硬截断;加一层上下渐隐后,
|
||||
* 切断处变成渐隐(2026-09-14 用户:「内容项上下滑动会直接被切断」)。
|
||||
*
|
||||
* ArkUI 的对应物是 `List.fadingEdge(true, { fadingEdgeLength })`(API 14+),
|
||||
* **不要**手捧渐变色遮罩:那是拿背景色画一个不存在的“底色”,
|
||||
* 在壁纸/玻璃主题下会露馅。
|
||||
*
|
||||
* 取 12:与 WebUI 的 `min(12px, 10%)` 同量级,也接近列表内边距(10vp),
|
||||
* 静止时几乎看不出,滚动时才起作用。
|
||||
*/
|
||||
export const LIST_FADE_LENGTH: number = 12;
|
||||
|
||||
/** 把任意下标归一化到内容窗格的合法范围(点击/外部传值都过这里,别直接赋值) */
|
||||
export function normalizeNavIndex(index: number): number {
|
||||
if (index >= 0 && index < NAV_CONTENT_COUNT) {
|
||||
|
||||
@ -68,7 +68,9 @@ import { MailDetailParams, ComposeParams } from '../model/RouteParams';
|
||||
* 这条注释留在 **import 区**而不是跟着表走,因为要守的是"import 在最前"这个位置本身。
|
||||
*/
|
||||
import { CalendarPage } from './CalendarPage';
|
||||
import { LengthMetrics } from '@kit.ArkUI';
|
||||
import {
|
||||
LIST_FADE_LENGTH,
|
||||
NAV_BAR_BOTTOM,
|
||||
NAV_BAR_HEIGHT,
|
||||
NAV_BAR_RADIUS,
|
||||
@ -475,6 +477,8 @@ struct InboxTab {
|
||||
}, (g: SessionGroup) => g.key)
|
||||
}
|
||||
.width('100%').layoutWeight(1)
|
||||
/* WebUI `.overflow-y-auto` 的上下渐隐(mask-image):卡片滑到边缘不硬截断 */
|
||||
.fadingEdge(true, { fadingEdgeLength: LengthMetrics.vp(LIST_FADE_LENGTH) })
|
||||
.padding({ left: 10, right: 10, top: 10, bottom: 10 })
|
||||
}
|
||||
}
|
||||
@ -846,6 +850,7 @@ struct SentTab {
|
||||
}, (g: SessionGroup) => g.key)
|
||||
}
|
||||
.width('100%').layoutWeight(1)
|
||||
.fadingEdge(true, { fadingEdgeLength: LengthMetrics.vp(LIST_FADE_LENGTH) })
|
||||
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
|
||||
}
|
||||
}
|
||||
@ -1078,6 +1083,7 @@ struct PermissionTab {
|
||||
}, (req: PermissionRequest) => req.request_id)
|
||||
}
|
||||
.width('100%').layoutWeight(1)
|
||||
.fadingEdge(true, { fadingEdgeLength: LengthMetrics.vp(LIST_FADE_LENGTH) })
|
||||
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
|
||||
}
|
||||
}
|
||||
@ -1358,6 +1364,7 @@ struct ContactsTab {
|
||||
}, (_c: Contact, idx: number) => idx.toString())
|
||||
}
|
||||
.width('100%').layoutWeight(1)
|
||||
.fadingEdge(true, { fadingEdgeLength: LengthMetrics.vp(LIST_FADE_LENGTH) })
|
||||
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
|
||||
} else {
|
||||
// 列表视图:同样**每项一张卡**(不再用贯通分隔线)—— 与卡片视图同一语义
|
||||
@ -1373,6 +1380,7 @@ struct ContactsTab {
|
||||
}, (_c: Contact, idx: number) => idx.toString())
|
||||
}
|
||||
.width('100%').layoutWeight(1)
|
||||
.fadingEdge(true, { fadingEdgeLength: LengthMetrics.vp(LIST_FADE_LENGTH) })
|
||||
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user