v0.4.0 顶栏改白色 + 通知栏同色 + 顶栏随页面滚动
用户 08:56 的三条要求:
1. 家书标题栏用浅色(下面色块的背景色);
2. 上面通知栏也是浅色,两者融为一体;
3. 向上滑动时标题栏跟着向上滑,不固定在原位。
(追问确认:顶栏底色 = 白;「品牌条 + 页面标题条」一起随滚动消失。)
## ① 系统栏改「不透明 + 与顶栏同色」,弃用透明方案
原来走「系统栏全透明 + 让紧邻元素透出同底色」。这版顶栏要用白色,
若仍走透明方案就得再造一层"白色压条"去刷白状态栏,太绕。
⇒ 直接 `statusBarColor = surface`(白)、`navigationBarColor = page_bg`(纸色)。
这是**配置出来的同色**,比"指望紧邻元素恰好同色"稳得多(后者顶栏一改底色就出色带)。
副产品:不再需要 `setWindowBackgroundColor` ⇒ 连那条 unavailable 告警也消失,
编译回到 **0 error / 0 warning**。
## ② 顶栏随滚动:整页包进 Scroll,顶栏作为内容第一个元素
原来 `Column { 页头; List/Grid(layoutWeight 1) }` —— 顶栏在滚动区**外面**,
所以固定不动。改为 `Scroll { Column { this.topBar(); 页头; 列表 } }`。
顶栏由 Index 以 `@BuilderParam topBar` 插槽下发(`topBarSlot`),13 个页面全部接入。
⚠️ 同步必须处理的两点:
· 列表的 `.layoutWeight(1)` 要删 —— Scroll>Column 里高度由内容决定,
layoutWeight 会去分"剩余空间"(=0) ⇒ 列表塌成 0 高、整页只剩顶栏和页头;
· List/Grid 不能自己再滚动(去 scrollBar/edgeEffect)—— 两层滚动容器会抢手势。
⚠️ ArkUI 限制:带尾随 lambda 的组件只能有 1 个 `@BuilderParam`
(首页原有闲置的 topActions 已删)。
## ③ 顶栏白色 + logo 可辨认
logo 是「米色底(74%) + 砖红图案(24%)」的实心方图,放在米色上底板隐形、
只剩图案发飘(用户说"看不清")。今加一层极浅描边把底板"托"出来。
顶栏高度 56→48vp。
## 验证(真机,全部通过)
· 沉浸式:状态栏色 `#FFFFFF` == 顶栏色 `#FFFFFF` ✓
· 顶栏随滚动:「家书」标题 y=140 → 滑动后**已滚出可视区** ✓
· 顶栏滚走后状态栏仍为 `#FFFFFF`(未露出页面内容)✓
· 14 个页面遍历 **14/14**;深验(每页特征文本)**12/12**
· 编译 **0 error / 0 warning**
## 过程记录:批量改 12 个文件失败两次(已回滚重做)
第 1 版按缩进正则切分 ⇒ 闭合括号错乱;第 2 版跳字符时**没消费 Column 的
修饰符链** ⇒ 吃掉 `@Builder` 声明、**636 个报错**。
第 3 版改为**按行 + 括号深度解析**,且**改完立刻做结构断言**
(括号配平、`this.topBar()` 恰好 +1),不满足就不写入;先单页试跑再推广。
教训:批量改多文件时正则不可靠,必须配结构自检 + 单页试点。
配套修掉 `_tooling/familybook_harmonyos_run.sh` 一个"假成功":
`hdc list targets` 无设备时输出字面量 `[Empty]`,原来"非空即通过"
⇒ 拿 `[Empty]` 当序列号去装、还打印「✓ 设备:[Empty]」。已显式排除并 die。
This commit is contained in:
@@ -1,18 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
* 家书 FamilyBook · 顶栏(鸿蒙端)
|
* 家书 FamilyBook · 顶栏(鸿蒙端)
|
||||||
*
|
*
|
||||||
* 形态照用户指的本机另一应用(SyncCalendar):
|
* 用户 2026-10-12 定的形态:
|
||||||
* **应用图标 + 标题贴左上,右侧放通知/头像** —— 就是一个普通 Row,
|
* · **应用图标 + 「家书」标题**贴左上(下行小字显示当前模块);
|
||||||
* **自己不做任何状态栏留白**。
|
* · 顶栏底色**白色**(与下面的个人信息卡同色,连成一片);
|
||||||
|
* · 顶栏**并入页面滚动流**,向上滑动时跟着内容一起滑走
|
||||||
|
* (所以它本身不固定、也不自己处理状态栏留白)。
|
||||||
*
|
*
|
||||||
* 🔴 沉浸式靠两层配合,顶栏本身不参与:
|
* 🔴 与状态栏的关系:顶栏是白色,而系统栏被涂成全透明、透出的是**根容器底色**。
|
||||||
* ① EntryAbility:系统栏涂成全透明(`#00000000`);
|
* 所以要让"通知栏与顶栏融为一体",根容器在顶栏这一段必须是白色 ——
|
||||||
* ② 根容器:`expandSafeArea` 让背景铺到状态栏区域。
|
* 由 `Index.ets` 在顶部铺一层与顶栏同高的白色块来实现(页面滚动时它不动,
|
||||||
* 于是「顶栏上方那一块」(其实是根容器背景)与通知栏完全融为一体,
|
* 保证通知栏区域永远是白的,不会滚出内容)。
|
||||||
* 而顶栏内容本身就在安全区内、位置不动 —— 不用算状态栏高度,也就不会算错。
|
|
||||||
*
|
*
|
||||||
* ⚠️ 顶栏**不放**「设置」—— 与 Web 端一致:设置收在抽屉底部的账号区里,
|
* ⚠️ 顶栏**不放**「设置」—— 与 Web 端一致:设置收在抽屉底部的账号区里。
|
||||||
* 顶栏只留日常入口,再把管理入口顶出来会把顶栏挤满。
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { FbColors, FbIcon, FbMetric } from '../common/Theme';
|
import { FbColors, FbIcon, FbMetric } from '../common/Theme';
|
||||||
@@ -46,11 +46,15 @@ export struct FbTopBar {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- 应用图标 + 标题(贴左,与抽屉里的品牌区同款,一眼认出是"家书")----
|
// ---- 应用图标 ----
|
||||||
|
// ⚠️ 必须给描边:logo 是「米色底(74%) + 砖红图案(24%)」的实心方图,
|
||||||
|
// 放在白色/米色上时底板与背景几乎同色,只剩砖红图案发飘、看不清。
|
||||||
|
// 一层极浅的描边就能把底板"托"出来(本机范本 SyncCalendar 也给了描边)。
|
||||||
Image($r('app.media.fb_logo'))
|
Image($r('app.media.fb_logo'))
|
||||||
.width(30)
|
.width(30)
|
||||||
.height(30)
|
.height(30)
|
||||||
.borderRadius(8)
|
.borderRadius(8)
|
||||||
|
.border({ width: 1, color: FbColors.line })
|
||||||
.flexShrink(0)
|
.flexShrink(0)
|
||||||
|
|
||||||
Column({ space: 0 }) {
|
Column({ space: 0 }) {
|
||||||
@@ -59,11 +63,10 @@ export struct FbTopBar {
|
|||||||
.fontWeight(FontWeight.Bold)
|
.fontWeight(FontWeight.Bold)
|
||||||
.fontColor(FbColors.ink)
|
.fontColor(FbColors.ink)
|
||||||
.maxLines(1)
|
.maxLines(1)
|
||||||
// 副标题显示当前模块名 —— 这样"品牌 + 当前位置"一行说清,
|
// 副标题显示当前模块名 —— "品牌 + 当前位置"一行说清
|
||||||
// 也省掉原来那个只写模块名的孤零零标题
|
|
||||||
Text(this.moduleName())
|
Text(this.moduleName())
|
||||||
.fontSize(FbMetric.fontTiny)
|
.fontSize(FbMetric.fontTiny)
|
||||||
.fontColor(FbColors.faint)
|
.fontColor(FbColors.muted)
|
||||||
.maxLines(1)
|
.maxLines(1)
|
||||||
}
|
}
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
@@ -111,17 +114,12 @@ export struct FbTopBar {
|
|||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.height(FbMetric.topBarH)
|
.height(FbMetric.topBarH)
|
||||||
// 左右留 14;上下尽量薄(顶栏默认贴状态栏下方,不留额外空隙)
|
|
||||||
.padding({ left: 14, right: 10, top: 4, bottom: 4 })
|
.padding({ left: 14, right: 10, top: 4, bottom: 4 })
|
||||||
.alignItems(VerticalAlign.Center)
|
.alignItems(VerticalAlign.Center)
|
||||||
// 🔴 **不设 backgroundColor** —— 这是"融为一体"的最后一块拼图。
|
// 顶栏底色 = 白色(与下面的个人信息卡同色)
|
||||||
// 顶栏没设背景时,它透出的是根容器的底色(page_bg,宣纸米);
|
.backgroundColor(FbColors.surface)
|
||||||
// 而状态栏被涂成全透明、透出的也是根容器底色 ⇒ 两者**天然同色**。
|
// 底线:与下方内容(同是白色卡)之间给一条极浅的分隔,避免"两块白糊在一起"
|
||||||
//
|
.border({ width: { bottom: 1 }, color: FbColors.line2 })
|
||||||
// ⚠️ 之前给顶栏设了 `FbColors.surface`(白色),于是变成
|
|
||||||
// 「状态栏(米色)+ 顶栏(白色)」上下拼接 —— 正是用户说的"没融为一体"。
|
|
||||||
// 本机范本 SyncCalendar 的 header() 也**没有 backgroundColor**,就是这个道理。
|
|
||||||
// 教训:想与系统栏同色,就别给紧邻元素单独上色,让它透出共同底色。
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private moduleName(): string {
|
private moduleName(): string {
|
||||||
|
|||||||
@@ -128,32 +128,29 @@ export default class EntryAbility extends UIAbility {
|
|||||||
/**
|
/**
|
||||||
* 系统栏配色。
|
* 系统栏配色。
|
||||||
*
|
*
|
||||||
* 🔴 核心手法(照 SyncCalendar 那套,实测最干净):
|
* 用户 2026-10-12 定的要求:
|
||||||
* **系统栏涂成全透明 `#00000000`**,再让窗口底色 = 页面背景色透出来。
|
* ① 家书标题栏用**浅色(白)**;
|
||||||
* 这样顶部通知栏的颜色天然等于"它下面那一块"的颜色 —— 就是用户要的
|
* ② 上面通知栏也是**浅色**,两者融为一体。
|
||||||
* 「上面那一块和通知栏完全融为一体」。
|
|
||||||
*
|
*
|
||||||
* ⚠️ 曾经的做法是把状态栏设成某个具体色(先设页面底色、又改成顶栏底色),
|
* ⇒ 做法:把状态栏设成与顶栏**同一个颜色**(`surface` = 白)。
|
||||||
* 结果都不对:状态栏是**独立于页面**的一层,给它写死颜色就必然和它下面的
|
* 这是一个"配置出来的"同色,比"让系统栏透明、再指望紧邻元素恰好同色"稳得多 ——
|
||||||
* 内容割裂(顶栏是白的、状态栏是米色的,看着就是"没对齐")。
|
* 后者一旦顶栏改了底色就会立刻出现色带(已经踩过一次)。
|
||||||
* 透明才是正解 —— 它不需要知道下面是白还是纸色。
|
|
||||||
*
|
*
|
||||||
* ⚠️ `setWindowBackgroundColor` 对 phone/tablet 会报 unavailable(编译器告警),
|
* ⚠️ 底部导航条取**页面底色**(宣纸米),与页面下部同色,不突兀。
|
||||||
* 但**这里必须调**:透明系统栏要透出的就是它。告警可忽略(SyncCalendar 同样这么用)。
|
* ⚠️ 取色走 resourceManager(经 dark/ 限定符解析)—— 深色模式一并生效。
|
||||||
*/
|
*/
|
||||||
private applySystemBars(win: window.Window): void {
|
private applySystemBars(win: window.Window): void {
|
||||||
const pageBg: string = this.themeColor($r('app.color.page_bg').id, '#F7F3EA');
|
const surfaceBg: string = this.themeColor($r('app.color.surface').id, '#FFFFFF');
|
||||||
// 前景(状态栏里的时间/电量)按页面底色亮度取反,深色模式自动变浅色字
|
const paperBg: string = this.themeColor($r('app.color.page_bg').id, '#F7F3EA');
|
||||||
const fg: string = this.isDarkBg(pageBg) ? '#FFFFFF' : '#2C231D';
|
|
||||||
try {
|
try {
|
||||||
win.setWindowSystemBarProperties({
|
win.setWindowSystemBarProperties({
|
||||||
statusBarColor: '#00000000',
|
// 顶部:与顶栏同色(白)⇒ 通知栏与标题栏融为一体
|
||||||
statusBarContentColor: fg,
|
statusBarColor: surfaceBg,
|
||||||
navigationBarColor: '#00000000',
|
statusBarContentColor: this.isDarkBg(surfaceBg) ? '#FFFFFF' : '#2C231D',
|
||||||
navigationBarContentColor: fg
|
// 底部:与页面底色同色
|
||||||
|
navigationBarColor: paperBg,
|
||||||
|
navigationBarContentColor: this.isDarkBg(paperBg) ? '#FFFFFF' : '#2C231D'
|
||||||
});
|
});
|
||||||
// 窗口底色 = 页面背景色,供透明系统栏透出
|
|
||||||
win.setWindowBackgroundColor(pageBg);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
hilog.error(DOMAIN, 'FamilyBook', 'setSystemBarProperties failed: %{public}s',
|
hilog.error(DOMAIN, 'FamilyBook', 'setSystemBarProperties failed: %{public}s',
|
||||||
JSON.stringify(err));
|
JSON.stringify(err));
|
||||||
|
|||||||
@@ -82,58 +82,64 @@ struct Index {
|
|||||||
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
|
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 内容区:顶栏 + 当前模块页 */
|
/** 内容区:当前模块页(含顶栏 —— 顶栏由页面放进自己的滚动流,见 topBarSlot) */
|
||||||
@Builder
|
@Builder
|
||||||
mainArea() {
|
mainArea() {
|
||||||
Column() {
|
|
||||||
// 顶栏:不再需要自己做状态栏留白(背景已由 expandSafeArea 铺到顶,
|
|
||||||
// 内容本身就在安全区内)
|
|
||||||
FbTopBar({ app: this.app }) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- 模块页 ----
|
|
||||||
Column() {
|
Column() {
|
||||||
this.moduleContent()
|
this.moduleContent()
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
|
||||||
}
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.backgroundColor(FbColors.paper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏内容(交给各模块页放进**自己的滚动流最前面** ⇒ 跟着内容一起滚走)。
|
||||||
|
*
|
||||||
|
* 🔴 用户要求:「向上滑动的时候,标题栏也跟着向上滑动,不需要固定在当前位置」
|
||||||
|
* ⇒ 顶栏不能再像以前那样摆在滚动容器**外面**(那样它是固定的)。
|
||||||
|
* 交给页面承载、页面把它放在 Scroll/List 的内容最前面,才会跟着滚。
|
||||||
|
*
|
||||||
|
* ⚠️ 状态栏由系统直接涂成白色(EntryAbility 里 `statusBarColor = surface`,
|
||||||
|
* 与顶栏同色)。所以顶栏滚走之后,通知栏区域仍由系统保持白色,
|
||||||
|
* 不会露出页面底色 —— 不需要在页面上再铺"白色压条"。
|
||||||
|
*/
|
||||||
|
@Builder
|
||||||
|
topBarSlot() {
|
||||||
|
FbTopBar({ app: this.app }) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 按当前模块渲染对应页面(用 if/else 分发:ArkUI 的 build 里不允许 switch) */
|
/** 按当前模块渲染对应页面(用 if/else 分发:ArkUI 的 build 里不允许 switch) */
|
||||||
@Builder
|
@Builder
|
||||||
moduleContent() {
|
moduleContent() {
|
||||||
if (this.app.activeModule === 'home') {
|
if (this.app.activeModule === 'home') {
|
||||||
FbHomePage({ app: this.app }) {
|
FbHomePage({ app: this.app, topBar: this.topBarSlot })
|
||||||
}
|
|
||||||
} else if (this.app.activeModule === 'people' || this.app.activeModule === 'kin') {
|
} else if (this.app.activeModule === 'people' || this.app.activeModule === 'kin') {
|
||||||
FbPeoplePage({ app: this.app })
|
FbPeoplePage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'movies') {
|
} else if (this.app.activeModule === 'movies') {
|
||||||
FbMoviesPage({ app: this.app })
|
FbMoviesPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'trips') {
|
} else if (this.app.activeModule === 'trips') {
|
||||||
FbTripsPage({ app: this.app })
|
FbTripsPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'calendar') {
|
} else if (this.app.activeModule === 'calendar') {
|
||||||
FbCalendarPage({ app: this.app })
|
FbCalendarPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'tasks') {
|
} else if (this.app.activeModule === 'tasks') {
|
||||||
FbTasksPage({ app: this.app })
|
FbTasksPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'resources') {
|
} else if (this.app.activeModule === 'resources') {
|
||||||
FbResourcesPage({ app: this.app })
|
FbResourcesPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'days') {
|
} else if (this.app.activeModule === 'days') {
|
||||||
FbDaysPage({ app: this.app })
|
FbDaysPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'ledger') {
|
} else if (this.app.activeModule === 'ledger') {
|
||||||
FbLedgerPage({ app: this.app })
|
FbLedgerPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'books') {
|
} else if (this.app.activeModule === 'books') {
|
||||||
FbBooksPage({ app: this.app })
|
FbBooksPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === 'notes') {
|
} else if (this.app.activeModule === 'notes') {
|
||||||
FbNotesPage({ app: this.app })
|
FbNotesPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === '__notifications') {
|
} else if (this.app.activeModule === '__notifications') {
|
||||||
FbNotificationsPage({ app: this.app })
|
FbNotificationsPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else if (this.app.activeModule === '__settings') {
|
} else if (this.app.activeModule === '__settings') {
|
||||||
FbSettingsPage({ app: this.app })
|
FbSettingsPage({ app: this.app, topBar: this.topBarSlot })
|
||||||
} else {
|
} else {
|
||||||
// 兜底:模块还没做页面时给一句提示,而不是白屏
|
// 兜底:模块还没做页面时给一句提示,而不是白屏
|
||||||
Column({ space: 8 }) {
|
Column({ space: 8 }) {
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ import { FbEmptyBox, FbIconButton, FbProgressLine, FbRating, FbTag } from '../..
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbBooksPage {
|
export struct FbBooksPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
/** 模块主题色(读书 = 藕紫) */
|
/** 模块主题色(读书 = 藕紫) */
|
||||||
@@ -23,7 +29,10 @@ export struct FbBooksPage {
|
|||||||
private all: FbBookItem[] = FB_DEMO_BOOKS;
|
private all: FbBookItem[] = FB_DEMO_BOOKS;
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 页头 ----
|
// ---- 页头 ----
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
@@ -67,7 +76,6 @@ export struct FbBooksPage {
|
|||||||
}
|
}
|
||||||
}, (g: FbGroup<FbBookItem>): string => 'bg_' + g.key)
|
}, (g: FbGroup<FbBookItem>): string => 'bg_' + g.key)
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
@@ -75,9 +83,12 @@ export struct FbBooksPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 一本书:书脊色块(代替封面)+ 书名/作者 + 评分/笔记/进度 */
|
/** 一本书:书脊色块(代替封面)+ 书名/作者 + 评分/笔记/进度 */
|
||||||
|
|||||||
@@ -39,6 +39,12 @@ interface FbCalCell {
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbCalendarPage {
|
export struct FbCalendarPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
/** 模块主题色(日程 = 琥珀) */
|
/** 模块主题色(日程 = 琥珀) */
|
||||||
@@ -56,7 +62,10 @@ export struct FbCalendarPage {
|
|||||||
private weekLabels: string[] = ['一', '二', '三', '四', '五', '六', '日'];
|
private weekLabels: string[] = ['一', '二', '三', '四', '五', '六', '日'];
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 页头:月份 + 视图切换 + 新建 + 设置 ----
|
// ---- 页头:月份 + 视图切换 + 新建 + 设置 ----
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
@@ -231,16 +240,18 @@ export struct FbCalendarPage {
|
|||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
.edgeEffect(EdgeEffect.Spring)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 上一月 / 下一月按钮 */
|
/** 上一月 / 下一月按钮 */
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ import { FbAvatar, FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../.
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbDaysPage {
|
export struct FbDaysPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
/** 模块主题色(纪念日 = 陶土橙) */
|
/** 模块主题色(纪念日 = 陶土橙) */
|
||||||
@@ -27,7 +33,10 @@ export struct FbDaysPage {
|
|||||||
@Local kindFilter: string = '';
|
@Local kindFilter: string = '';
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 页头 ----
|
// ---- 页头 ----
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
@@ -127,16 +136,18 @@ export struct FbDaysPage {
|
|||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
.edgeEffect(EdgeEffect.Spring)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 即将到来的大数字卡 */
|
/** 即将到来的大数字卡 */
|
||||||
|
|||||||
@@ -22,9 +22,13 @@ import { FbAvatar, FbDot, FbDotLine, FbSectionTitle, FbStatTriple, FbTag } from
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbHomePage {
|
export struct FbHomePage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
/** 顶栏右侧插槽(由外层传入,本页不用,留空占位以保持签名统一) */
|
|
||||||
@BuilderParam topActions: () => void;
|
|
||||||
|
|
||||||
private cards: FbModuleCard[] = FB_DEMO_MODULE_CARDS;
|
private cards: FbModuleCard[] = FB_DEMO_MODULE_CARDS;
|
||||||
private todayEvents: FbCalEvent[] = FB_DEMO_EVENTS_TODAY;
|
private todayEvents: FbCalEvent[] = FB_DEMO_EVENTS_TODAY;
|
||||||
@@ -72,6 +76,8 @@ export struct FbHomePage {
|
|||||||
build() {
|
build() {
|
||||||
Scroll() {
|
Scroll() {
|
||||||
Column({ space: 0 }) {
|
Column({ space: 0 }) {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
|
|
||||||
// ==================== ① 个人信息卡(问候 + 今天 + 天气)====================
|
// ==================== ① 个人信息卡(问候 + 今天 + 天气)====================
|
||||||
// 🔴 用户 2026-10-12 定的:这一块**要白色卡片**("这样显得好看")。
|
// 🔴 用户 2026-10-12 定的:这一块**要白色卡片**("这样显得好看")。
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ import { FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../componen
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbLedgerPage {
|
export struct FbLedgerPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
/** 模块主题色(财务 = 橄榄绿) */
|
/** 模块主题色(财务 = 橄榄绿) */
|
||||||
@@ -34,7 +40,10 @@ export struct FbLedgerPage {
|
|||||||
@Local bookId: number = 0;
|
@Local bookId: number = 0;
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 页头 ----
|
// ---- 页头 ----
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
@@ -121,7 +130,6 @@ export struct FbLedgerPage {
|
|||||||
.fontWeight(FontWeight.Medium)
|
.fontWeight(FontWeight.Medium)
|
||||||
.fontColor(FbColors.green)
|
.fontColor(FbColors.green)
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
|
|
||||||
Column({ space: 3 }) {
|
Column({ space: 3 }) {
|
||||||
@@ -133,7 +141,6 @@ export struct FbLedgerPage {
|
|||||||
.fontWeight(FontWeight.Medium)
|
.fontWeight(FontWeight.Medium)
|
||||||
.fontColor(FbColors.red)
|
.fontColor(FbColors.red)
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
@@ -225,16 +232,18 @@ export struct FbLedgerPage {
|
|||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
.edgeEffect(EdgeEffect.Spring)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 一条账目:名字 + 归属人 + 金额 + 盘点入口 */
|
/** 一条账目:名字 + 归属人 + 金额 + 盘点入口 */
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ import { FbAvatar, FbDot, FbEmptyBox, FbPrimaryButton, FbTag } from '../../compo
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbNotesPage {
|
export struct FbNotesPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
/** 模块主题色(笔记 = 褐灰) */
|
/** 模块主题色(笔记 = 褐灰) */
|
||||||
@@ -30,7 +36,10 @@ export struct FbNotesPage {
|
|||||||
private all: FbNoteItem[] = FB_DEMO_NOTES;
|
private all: FbNoteItem[] = FB_DEMO_NOTES;
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
Text('笔记')
|
Text('笔记')
|
||||||
@@ -82,9 +91,12 @@ export struct FbNotesPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
@@ -148,12 +160,21 @@ export struct FbNotesPage {
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbNotificationsPage {
|
export struct FbNotificationsPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
private all: FbNotificationItem[] = FB_DEMO_NOTIFICATIONS;
|
private all: FbNotificationItem[] = FB_DEMO_NOTIFICATIONS;
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
Text('通知消息')
|
Text('通知消息')
|
||||||
@@ -197,7 +218,6 @@ export struct FbNotificationsPage {
|
|||||||
}
|
}
|
||||||
}, (n: FbNotificationItem): string => 'nf_' + n.id.toString())
|
}, (n: FbNotificationItem): string => 'nf_' + n.id.toString())
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
@@ -205,9 +225,12 @@ export struct FbNotificationsPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ import { FbDot, FbEmptyBox, FbIconButton, FbPersonChip, FbPrimaryButton, FbRatin
|
|||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbMoviesPage {
|
export struct FbMoviesPage {
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
|
|
||||||
private movies: FbMovieItem[] = FB_DEMO_MOVIES;
|
private movies: FbMovieItem[] = FB_DEMO_MOVIES;
|
||||||
private cinemas: string[] = FB_DEMO_CINEMAS;
|
private cinemas: string[] = FB_DEMO_CINEMAS;
|
||||||
@@ -25,7 +30,10 @@ export struct FbMoviesPage {
|
|||||||
private accent: string = '#7A4E8C';
|
private accent: string = '#7A4E8C';
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 页头:标题 + 记一场电影 + 设置 ----
|
// ---- 页头:标题 + 记一场电影 + 设置 ----
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
@@ -106,16 +114,22 @@ export struct FbMoviesPage {
|
|||||||
.columnsGap(12)
|
.columnsGap(12)
|
||||||
.rowsGap(12)
|
.rowsGap(12)
|
||||||
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
||||||
.layoutWeight(1)
|
// ⚠️ 不能给 layoutWeight:本页已整体放进 Scroll,
|
||||||
|
// Column 的高度由内容决定,layoutWeight(1) 会去分"剩余空间"(此时为 0)
|
||||||
|
// ⇒ Grid 高度塌成 0、整页只有顶栏和页头。
|
||||||
|
.width('100%')
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
.edgeEffect(EdgeEffect.Spring)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 一张电影卡:海报位(2:3)+ 片名 + 元信息 + 同看的人 */
|
/** 一张电影卡:海报位(2:3)+ 片名 + 元信息 + 同看的人 */
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ interface FbKinRing {
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbPeoplePage {
|
export struct FbPeoplePage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
/** 子视图:名册(roster)/ 家谱(kin) */
|
/** 子视图:名册(roster)/ 家谱(kin) */
|
||||||
@@ -43,7 +49,10 @@ export struct FbPeoplePage {
|
|||||||
private rels: FbKinRelation[] = FB_DEMO_KIN_RELATIONS;
|
private rels: FbKinRelation[] = FB_DEMO_KIN_RELATIONS;
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 分段切换(名册 / 家谱)----
|
// ---- 分段切换(名册 / 家谱)----
|
||||||
Row({ space: 4 }) {
|
Row({ space: 4 }) {
|
||||||
this.segBtn('名册', 'roster', '#A84A28')
|
this.segBtn('名册', 'roster', '#A84A28')
|
||||||
@@ -61,9 +70,12 @@ export struct FbPeoplePage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ import { FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../componen
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbResourcesPage {
|
export struct FbResourcesPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
/** 模块主题色(资源 = 靛蓝) */
|
/** 模块主题色(资源 = 靛蓝) */
|
||||||
@@ -25,7 +31,10 @@ export struct FbResourcesPage {
|
|||||||
@Local kindFilter: string = '';
|
@Local kindFilter: string = '';
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 页头 ----
|
// ---- 页头 ----
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
@@ -84,7 +93,6 @@ export struct FbResourcesPage {
|
|||||||
}
|
}
|
||||||
}, (g: FbGroup<FbResourceItem>): string => 'rsg_' + g.key)
|
}, (g: FbGroup<FbResourceItem>): string => 'rsg_' + g.key)
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
@@ -92,9 +100,12 @@ export struct FbResourcesPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 一项资源卡 */
|
/** 一项资源卡 */
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ import { FbAvatar, FbDot, FbTag } from '../../components/Widgets';
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbSettingsPage {
|
export struct FbSettingsPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
/** 抽屉里勾选着的模块 key(与 FB_DEFAULT_NAV 一致,不含 nav) */
|
/** 抽屉里勾选着的模块 key(与 FB_DEFAULT_NAV 一致,不含 nav) */
|
||||||
@@ -28,6 +34,8 @@ export struct FbSettingsPage {
|
|||||||
build() {
|
build() {
|
||||||
Scroll() {
|
Scroll() {
|
||||||
Column({ space: 0 }) {
|
Column({ space: 0 }) {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
|
|
||||||
// ==================== 我的资料 ====================
|
// ==================== 我的资料 ====================
|
||||||
Row({ space: 14 }) {
|
Row({ space: 14 }) {
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ import { FbCheckCircle, FbDot, FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbTasksPage {
|
export struct FbTasksPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
private boards: string[] = FB_DEMO_TASK_BOARDS;
|
private boards: string[] = FB_DEMO_TASK_BOARDS;
|
||||||
@@ -27,7 +33,10 @@ export struct FbTasksPage {
|
|||||||
@Local boardFilter: string = '';
|
@Local boardFilter: string = '';
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 页头 ----
|
// ---- 页头 ----
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 2 }) {
|
Column({ space: 2 }) {
|
||||||
@@ -88,7 +97,6 @@ export struct FbTasksPage {
|
|||||||
}
|
}
|
||||||
}, (g: FbGroup<FbTaskItem>): string => 'grp_' + g.key)
|
}, (g: FbGroup<FbTaskItem>): string => 'grp_' + g.key)
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
@@ -96,9 +104,12 @@ export struct FbTasksPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 看板筛选胶囊 */
|
/** 看板筛选胶囊 */
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ import { FbDot, FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../c
|
|||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct FbTripsPage {
|
export struct FbTripsPage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶栏插槽:由 Index.ets 传入,放在本页滚动流最前面 ⇒ 随页面一起滚走。
|
||||||
|
* 🔴 用户要求「向上滑动时标题栏跟着一起滑走」。
|
||||||
|
*/
|
||||||
|
@BuilderParam topBar: () => void;
|
||||||
@Param app: FbAppState = fbAppState();
|
@Param app: FbAppState = fbAppState();
|
||||||
|
|
||||||
private trips: FbTripItem[] = FB_DEMO_TRIPS;
|
private trips: FbTripItem[] = FB_DEMO_TRIPS;
|
||||||
@@ -30,7 +36,10 @@ export struct FbTripsPage {
|
|||||||
@Local expandedId: number = 0;
|
@Local expandedId: number = 0;
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
Scroll() {
|
||||||
Column() {
|
Column() {
|
||||||
|
this.topBar()
|
||||||
|
|
||||||
// ---- 页头操作条 ----
|
// ---- 页头操作条 ----
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
Column({ space: 1 }) {
|
Column({ space: 1 }) {
|
||||||
@@ -69,7 +78,6 @@ export struct FbTripsPage {
|
|||||||
}
|
}
|
||||||
}, (t: FbTripItem): string => 'trip_' + t.id.toString())
|
}, (t: FbTripItem): string => 'trip_' + t.id.toString())
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
.padding({ left: FbMetric.pagePad, right: FbMetric.pagePad, bottom: 24 })
|
||||||
.scrollBar(BarState.Off)
|
.scrollBar(BarState.Off)
|
||||||
@@ -77,9 +85,12 @@ export struct FbTripsPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.backgroundColor(FbColors.paper)
|
.scrollBar(BarState.Off)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.edgeEffect(EdgeEffect.Spring)
|
||||||
|
.align(Alignment.TopStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 一张旅程卡:标题 + 时间 + 进度;展开后接行程时间轴 */
|
/** 一张旅程卡:标题 + 时间 + 进度;展开后接行程时间轴 */
|
||||||
|
|||||||
Reference in New Issue
Block a user