diff --git a/entry/src/main/ets/components/FloatDock.ets b/entry/src/main/ets/components/FloatDock.ets new file mode 100644 index 0000000..a0e3126 --- /dev/null +++ b/entry/src/main/ets/components/FloatDock.ets @@ -0,0 +1,145 @@ +/** + * 家书 FamilyBook · 底部悬浮快捷栏(鸿蒙端) + * + * 用户 2026-10-12 要求: + * 「页面正下方设置几个浮动按钮,放三、四个常见功能。比如日程、名册、任务和笔记, + * 这四个应该比较常用,放在下面。这样用户不用拉抽屉,就可以直接点击使用。 + * 但一定要注意,使用浮动的方式,**不要固定在下面**,而是**浮动着的**。」 + * + * 🔴 形态照**鸿蒙 6 官方设计规范**的「悬浮导航(Float Navigation)」: + * · 脱离底部边界,以「**四周留白 + 圆角卡片**」形态**悬浮在内容之上**; + * · 参考实现参数:`height(56) + margin({left:16,right:16,bottom:16}) + borderRadius(28)`; + * · 材质用系统提供的沉浸材质(`uiMaterial.ImmersiveMaterial`, + * `ImmersiveStyle.ULTRA_THIN` 对应设计规范里的"超薄"档), + * 它自带模糊/边框/阴影 —— ⚠️ 用了它**不要**再叠加 backgroundBlurStyle, + * 否则会双重模糊、发灰。 + * · 与系统手势条保持间距,减少误触(所以就 `bottom:16` 而不是贴底)。 + * + * ⚠️ 为什么用 `Stack(alignContent: Bottom)` 覆盖在内容上,而不是在 Column 里占一行: + * 用户明确说"不要固定在下边,要浮着"。占一行就是"固定的底部栏"(老样式); + * 用 Stack 覆盖 ⇒ 内容从它下面穿过、它是浮在上面的。这是这个组件唯一正确的摆法。 + * + * ⚠️ "隐藏时不影响观感":内容底部要留出 `DOCK_RESERVE` 的空白, + * 否则最后一块内容会被悬浮栏压住(悬浮 ≠ 可以挡内容)。 + */ + +import { uiMaterial } from '@kit.ArkUI'; +import { FbColors, FbIcon, FbMetric } from '../common/Theme'; +import { FbAppState, fbAppState } from '../common/Store'; +import { FbModuleDef, fbModuleOf } from '../model/Modules'; + +/** 内容区为悬浮栏预留的高度(vp):栏高 56 + 下边距 16 + 一点余量 */ +export const FB_DOCK_RESERVE: number = 88; + +/** 快捷栏高度(vp)—— 取设计规范的 56 */ +const DOCK_H: number = 56; +/** 四周留白(vp)—— 设计规范给的是 16 */ +const DOCK_PAD: number = 16; + +/** + * 悬浮快捷栏。 + * + * @param app 全局状态(切模块用) + * @param keys 要放的模块 key(默认四个常用:日程 / 名册 / 任务 / 笔记) + */ +@ComponentV2 +export struct FbFloatDock { + @Param app: FbAppState = fbAppState(); + /** + * 快捷模块 key 列表。 + * 🔴 用户点名要这四个("应该比较常用"):日程、名册、任务、笔记。 + * 顺序按用户说的来。 + */ + @Param keys: string[] = ['calendar', 'people', 'tasks', 'notes']; + + build() { + Row() { + ForEach(this.keys, (k: string) => { + // 当前模块在快捷栏里高亮,让用户知道"我在哪" + this.dockItem(k, k === this.app.activeModule); + }, (k: string): string => 'dock_' + k) + } + .width('100%') + .height(DOCK_H) + // 四周留白 ⇒ 悬浮感(不贴屏幕边) + .margin({ left: DOCK_PAD, right: DOCK_PAD, bottom: DOCK_PAD }) + .padding({ left: 6, right: 6 }) + .borderRadius(DOCK_H / 2) // 全圆角胶囊形(28 = 56/2) + .alignItems(VerticalAlign.Center) + // 🔴 悬浮材质(鸿蒙 6 设计规范的"超薄沉浸"档)。 + // ⚠️ 这里**只**用 systemMaterial,不加 backgroundColor/backgroundBlurStyle —— + // 材质自带模糊与描边,叠加会双重模糊。 + // ⚠️ 若设备/版本不支持该 API,会在运行时被忽略(不崩), + // 所以下面再给一层极浅的描边兜底,保证"有边界的悬浮卡片"这个观感不丢。 + .systemMaterial(new uiMaterial.ImmersiveMaterial({ + style: uiMaterial.ImmersiveStyle.ULTRA_THIN + })) + .border({ width: 1, color: FbColors.line2 }) + // 浮在内容之上:给一点投影增强"悬浮"层次 + .shadow({ radius: 18, color: '#1A2C231D', offsetY: 6 }) + } + + /** 一个快捷项:图标 + 文字(竖排,紧凑) */ + @Builder + dockItem(key: string, active: boolean) { + Column({ space: 2 }) { + Image(FbIcon.ui(this.iconNameOf(key))) + .width(20) + .height(20) + .renderMode(ImageRenderMode.Template) + // ⚠️ fillColor 必须是同一类型:选中时用模块色(string), + // 未选中时用 `$r` 资源也可以,但**三目里两侧类型必须一致** + // (Resource 与 string 混用会报 "Type 'string | Resource' is not assignable to type 'string'")。 + // 这里统一走 string 色值,省掉类型打架。 + .fillColor(active ? this.accentOf(key) : '#7E6B5A') + Text(this.labelOf(key)) + .fontSize(FbMetric.fontTiny) + .fontColor(active ? this.accentOf(key) : '#7E6B5A') + .maxLines(1) + } + .layoutWeight(1) // 四等分 + .height('100%') + .justifyContent(FlexAlign.Center) + .onClick(() => { + // 切模块(switchModule 内部会顺手收起抽屉) + this.app.switchModule(key); + }) + } + + /** 模块名(取注册中心,避免各处写死) */ + private labelOf(key: string): string { + const m: FbModuleDef | undefined = fbModuleOf(key); + return m !== undefined ? m.name : key; + } + + /** 模块主题色(返回 **string 色值**,供 fillColor/fontColor 用) */ + private accentOf(key: string): string { + const m: FbModuleDef | undefined = fbModuleOf(key); + return m !== undefined ? m.color : '#A84A28'; + } + + /** + * 模块 → 图标名。 + * + * ⚠️ 这里必须显式映射,不能用 `fb_ic_ + key`:模块 key 与图标文件名并不一一对应 + * (people → fb_ic_people 对得上,但 notes → fb_ic_notes 也对得上…… + * 而将来若有 key 与文件名不一致的,拼串就会拿到 undefined 资源而崩)。 + * 显式写死更稳。 + */ + private iconNameOf(key: string): string { + switch (key) { + case 'calendar': return 'calendar'; + case 'people': return 'people'; + case 'tasks': return 'tasks'; + case 'notes': return 'notes'; + case 'home': return 'home'; + case 'movies': return 'movies'; + case 'trips': return 'trips'; + case 'resources': return 'resources'; + case 'days': return 'days'; + case 'ledger': return 'ledger'; + case 'books': return 'books'; + default: return 'home'; + } + } +} \ No newline at end of file diff --git a/entry/src/main/ets/components/TopBar.ets b/entry/src/main/ets/components/TopBar.ets index 5050073..ba87d51 100644 --- a/entry/src/main/ets/components/TopBar.ets +++ b/entry/src/main/ets/components/TopBar.ets @@ -3,15 +3,15 @@ * * 用户 2026-10-12 定的形态: * · **应用图标 + 「家书」标题**贴左上(下行小字显示当前模块); + * · **点图标 = 开抽屉**(用户要求:汉堡按钮去掉后,把这个功能挪到图标上); * · 顶栏底色**白色**(与下面的个人信息卡同色,连成一片); - * · 顶栏**并入页面滚动流**,向上滑动时跟着内容一起滑走 - * (所以它本身不固定、也不自己处理状态栏留白)。 + * · 顶栏**并入页面滚动流**,向上滑动时跟着内容一起滑走。 * - * 🔴 **顶栏不放汉堡按钮**(用户 2026-10-12 明确要求去掉): - * 开抽屉改由**屏幕边缘滑动**触发(见 `Drawer.ets` 的 parallelGesture)—— - * 从左边缘向右滑 ⇒ 抽屉在左;从右边缘向左滑 ⇒ 抽屉在右。 - * ⇒ 图标能一直贴到最左边,视觉上更好看。 - * ⚠️ 别再加回汉堡按钮;抽屉的其它入口是「顶栏头像」与「抽屉底部账号区」。 + * 🔴 开抽屉的三个入口: + * ① **点顶栏图标**(本组件)—— 用户新增要求; + * ② **应用内水平滑动**(向右滑→左边出、向左滑→右边出,见 `Drawer.ets`); + * ③ 底部**悬浮快捷栏**(首页几个常用模块直达,见 `Pages` 里的 FloatDock)。 + * ⚠️ 屏幕边缘是**系统手势区**,应用收不到,所以不做边缘滑动。 * * ⚠️ 顶栏**不放**「设置」—— 与 Web 端一致:设置收在抽屉底部的账号区里。 */ @@ -29,16 +29,23 @@ export struct FbTopBar { build() { Row({ space: 10 }) { - // ---- 应用图标(贴最左:抽屉改由边缘滑动触发,这里不再有汉堡按钮)---- + // ---- 应用图标(贴最左;**点它开抽屉**)---- // ⚠️ 必须给描边:logo 是「米色底(74%) + 砖红图案(24%)」的实心方图, // 放在白色/米色上时底板与背景几乎同色,只剩砖红图案发飘、看不清。 // 一层极浅的描边就能把底板"托"出来(本机范本 SyncCalendar 也给了描边)。 + // + // 🔴 点击事件直接挂在 Image 上,**不套 Button** —— + // Button 自带最小尺寸与内边距,会把图标挤离左边线(用户要"图标靠左")。 Image($r('app.media.fb_logo')) .width(30) .height(30) .borderRadius(8) .border({ width: 1, color: FbColors.line }) .flexShrink(0) + .onClick(() => { + // 点图标 ⇒ 开抽屉(沿用上次的方向 drawerSide,默认左边) + this.app.drawerOpen = true; + }) Column({ space: 0 }) { Text('家书') diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index f1f555c..64be443 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -18,6 +18,7 @@ import { FbColors, FbMetric } from '../common/Theme'; import { FbAppState, FB_WIDE_BREAKPOINT, fbAppState } from '../common/Store'; import { FbDrawerShell } from '../components/Drawer'; import { FbTopBar } from '../components/TopBar'; +import { FbFloatDock } from '../components/FloatDock'; import { FbHomePage } from './home/FbHomePage'; import { FbMoviesPage } from './movies/FbMoviesPage'; import { FbTripsPage } from './trips/FbTripsPage'; @@ -64,20 +65,28 @@ struct Index { } build() { - Column() { - FbDrawerShell({ app: this.app }) { - this.mainArea() + // 🔴 用 Stack 而不是 Column:底部快捷栏要**浮在内容之上**(用户要求"不要固定在下边, + // 要浮着")。写在 Column 里它就是"占一行的固定底栏"(老样式)。 + Stack({ alignContent: Alignment.Bottom }) { + Column() { + FbDrawerShell({ app: this.app }) { + this.mainArea() + } + } + .width('100%') + .height('100%') + + // 底部悬浮快捷栏(日程 / 名册 / 任务 / 笔记) + // ⚠️ 只在窄屏显示:宽屏时抽屉常驻,且屏幕宽,用不上这个快捷入口。 + // ⚠️ 抽屉展开时不显示 —— 那时用户正在抽屉里选模块,浮层再叠一个反而乱。 + if (!this.app.wideLayout && !this.app.drawerOpen) { + FbFloatDock({ app: this.app }) } } .width('100%') .height('100%') - // 🔴 沉浸式的全部秘诀在这一句(照 SyncCalendar 的写法): - // `expandSafeArea` 让**根容器的背景**延伸到状态栏/手势条区域, - // 但**不移动任何子组件** —— 内容仍在安全区内正常排版, - // 只有背景色一路铺到屏幕边缘。 - // 再配合 EntryAbility 里"系统栏全透明",顶部通知栏透出的就是这层背景色, - // 于是「上面那一块和通知栏完全融为一体」。 - // ⇒ 不需要手算状态栏高度、不需要给顶栏加 padding,也就不会算错。 + // 沉浸式:让**根容器背景**延伸到状态栏/手势条区域,但不移动子组件。 + // 配合 EntryAbility 里"系统栏与顶栏同色",通知栏与标题栏融为一体。 .backgroundColor(FbColors.paper) .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) } diff --git a/entry/src/main/ets/pages/books/FbBooksPage.ets b/entry/src/main/ets/pages/books/FbBooksPage.ets index 7f5a252..ba38fcb 100644 --- a/entry/src/main/ets/pages/books/FbBooksPage.ets +++ b/entry/src/main/ets/pages/books/FbBooksPage.ets @@ -13,6 +13,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbBookItem, FbGroup } from '../../model/Types'; import { FB_DEMO_BOOKS, fbGroupBook } from '../../model/DemoData'; import { FbEmptyBox, FbIconButton, FbProgressLine, FbRating, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbBooksPage { @@ -83,6 +84,8 @@ export struct FbBooksPage { } } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .height('100%') diff --git a/entry/src/main/ets/pages/calendar/FbCalendarPage.ets b/entry/src/main/ets/pages/calendar/FbCalendarPage.ets index f86b53a..d19c9aa 100644 --- a/entry/src/main/ets/pages/calendar/FbCalendarPage.ets +++ b/entry/src/main/ets/pages/calendar/FbCalendarPage.ets @@ -18,6 +18,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbCalBook, FbCalEvent } from '../../model/Types'; import { FB_DEMO_CAL_BOOKS, FB_DEMO_EVENTS_SOON, FB_DEMO_EVENTS_TODAY } from '../../model/DemoData'; import { FbDot, FbEmptyBox, FbIconButton, FbPrimaryButton } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; /** 月历上「非本月」日期点的灰(hex 常量:格子数据结构里存的是字符串色,不能用 Resource) */ const FB_FAINT: string = '#A8988A'; @@ -236,6 +237,8 @@ export struct FbCalendarPage { .margin({ left: FbMetric.pagePad, right: FbMetric.pagePad, top: 12, bottom: 28 }) } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .scrollBar(BarState.Off) diff --git a/entry/src/main/ets/pages/days/FbDaysPage.ets b/entry/src/main/ets/pages/days/FbDaysPage.ets index d2efdb3..420b869 100644 --- a/entry/src/main/ets/pages/days/FbDaysPage.ets +++ b/entry/src/main/ets/pages/days/FbDaysPage.ets @@ -15,6 +15,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbAnniversaryItem, FbKinChip } from '../../model/Types'; import { FB_DEMO_ANNIVERSARIES } from '../../model/DemoData'; import { FbAvatar, FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbDaysPage { @@ -96,6 +97,8 @@ export struct FbDaysPage { .scrollable(ScrollDirection.Horizontal) .scrollBar(BarState.Off) .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } } .padding(FbMetric.cardPad) diff --git a/entry/src/main/ets/pages/home/FbHomePage.ets b/entry/src/main/ets/pages/home/FbHomePage.ets index 0200175..6dc5fad 100644 --- a/entry/src/main/ets/pages/home/FbHomePage.ets +++ b/entry/src/main/ets/pages/home/FbHomePage.ets @@ -19,6 +19,7 @@ import { FB_DEMO_MODULE_CARDS, FB_DEMO_TASKS, FB_DEMO_WEATHER, FB_DEMO_WEEK_STAT } from '../../model/DemoData'; import { FbAvatar, FbDot, FbDotLine, FbSectionTitle, FbStatTriple, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbHomePage { @@ -153,6 +154,8 @@ export struct FbHomePage { }, (mk: string, idx: number): string => 'mk_' + idx.toString() + '_' + mk) } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .alignItems(HorizontalAlign.Start) diff --git a/entry/src/main/ets/pages/ledger/FbLedgerPage.ets b/entry/src/main/ets/pages/ledger/FbLedgerPage.ets index 6a456e8..8022bba 100644 --- a/entry/src/main/ets/pages/ledger/FbLedgerPage.ets +++ b/entry/src/main/ets/pages/ledger/FbLedgerPage.ets @@ -21,6 +21,7 @@ import { FB_DEMO_LEDGER_BOOKS, FB_DEMO_LEDGER_ENTRIES, fbLedgerKindName, fbMoney } from '../../model/DemoData'; import { FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbLedgerPage { @@ -217,6 +218,8 @@ export struct FbLedgerPage { }, (e: FbLedgerEntry): string => 'le_' + e.id.toString()) } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .padding(FbMetric.cardPad) .backgroundColor(FbColors.surface) diff --git a/entry/src/main/ets/pages/misc/FbMiscPages.ets b/entry/src/main/ets/pages/misc/FbMiscPages.ets index 85235f8..0496b92 100644 --- a/entry/src/main/ets/pages/misc/FbMiscPages.ets +++ b/entry/src/main/ets/pages/misc/FbMiscPages.ets @@ -16,6 +16,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbNoteItem, FbNotificationItem } from '../../model/Types'; import { FB_DEMO_NOTES, FB_DEMO_NOTIFICATIONS } from '../../model/DemoData'; import { FbAvatar, FbDot, FbEmptyBox, FbPrimaryButton, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; // ============================================================ // 笔记 @@ -91,6 +92,8 @@ export struct FbNotesPage { } } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .height('100%') diff --git a/entry/src/main/ets/pages/movies/FbMoviesPage.ets b/entry/src/main/ets/pages/movies/FbMoviesPage.ets index e3c0964..ac1e493 100644 --- a/entry/src/main/ets/pages/movies/FbMoviesPage.ets +++ b/entry/src/main/ets/pages/movies/FbMoviesPage.ets @@ -14,6 +14,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbMovieItem, FbKinChip } from '../../model/Types'; import { FB_DEMO_CINEMAS, FB_DEMO_MOVIES } from '../../model/DemoData'; import { FbDot, FbEmptyBox, FbIconButton, FbPersonChip, FbPrimaryButton, FbRating, FbSectionTitle } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbMoviesPage { @@ -123,6 +124,8 @@ export struct FbMoviesPage { } } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .height('100%') diff --git a/entry/src/main/ets/pages/people/FbPeoplePage.ets b/entry/src/main/ets/pages/people/FbPeoplePage.ets index 0e37553..392d077 100644 --- a/entry/src/main/ets/pages/people/FbPeoplePage.ets +++ b/entry/src/main/ets/pages/people/FbPeoplePage.ets @@ -17,6 +17,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbGroup, FbKinRelation, FbRosterItem } from '../../model/Types'; import { FB_DEMO_KIN_RELATIONS, FB_DEMO_ROSTER, fbGroupRoster } from '../../model/DemoData'; import { FbAvatar, FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; /** 家谱里一个人一圈的分组 */ interface FbKinRing { @@ -70,6 +71,8 @@ export struct FbPeoplePage { } } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .height('100%') diff --git a/entry/src/main/ets/pages/resources/FbResourcesPage.ets b/entry/src/main/ets/pages/resources/FbResourcesPage.ets index b03d19b..4614779 100644 --- a/entry/src/main/ets/pages/resources/FbResourcesPage.ets +++ b/entry/src/main/ets/pages/resources/FbResourcesPage.ets @@ -13,6 +13,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbGroup, FbResourceItem } from '../../model/Types'; import { FB_DEMO_RESOURCES, fbGroupResource } from '../../model/DemoData'; import { FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbResourcesPage { @@ -100,6 +101,8 @@ export struct FbResourcesPage { } } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .height('100%') diff --git a/entry/src/main/ets/pages/settings/FbSettingsPage.ets b/entry/src/main/ets/pages/settings/FbSettingsPage.ets index b9caadf..2817a3a 100644 --- a/entry/src/main/ets/pages/settings/FbSettingsPage.ets +++ b/entry/src/main/ets/pages/settings/FbSettingsPage.ets @@ -14,6 +14,7 @@ import { FbColors, FbMetric, fbPalette } from '../../common/Theme'; import { FbAppState, fbAppState } from '../../common/Store'; import { FbModuleDef, FB_MODULES, FB_PRESET_COLORS } from '../../model/Modules'; import { FbAvatar, FbDot, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbSettingsPage { @@ -153,6 +154,8 @@ export struct FbSettingsPage { .margin({ left: FbMetric.pagePad, right: FbMetric.pagePad, top: 12, bottom: 28 }) } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .height('100%') diff --git a/entry/src/main/ets/pages/tasks/FbTasksPage.ets b/entry/src/main/ets/pages/tasks/FbTasksPage.ets index 8592b74..a99406b 100644 --- a/entry/src/main/ets/pages/tasks/FbTasksPage.ets +++ b/entry/src/main/ets/pages/tasks/FbTasksPage.ets @@ -14,6 +14,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbGroup, FbTaskItem } from '../../model/Types'; import { FB_DEMO_TASK_BOARDS, FB_DEMO_TASKS, fbGroupTask } from '../../model/DemoData'; import { FbCheckCircle, FbDot, FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbTasksPage { @@ -104,6 +105,8 @@ export struct FbTasksPage { } } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .height('100%') diff --git a/entry/src/main/ets/pages/trips/FbTripsPage.ets b/entry/src/main/ets/pages/trips/FbTripsPage.ets index 3982cfb..5d4bb8c 100644 --- a/entry/src/main/ets/pages/trips/FbTripsPage.ets +++ b/entry/src/main/ets/pages/trips/FbTripsPage.ets @@ -17,6 +17,7 @@ import { FbAppState, fbAppState } from '../../common/Store'; import { FbTripItem, FbTripNode } from '../../model/Types'; import { FB_DEMO_TRIPS, FB_DEMO_TRIP_NODES, fbMoney } from '../../model/DemoData'; import { FbDot, FbEmptyBox, FbIconButton, FbPrimaryButton, FbTag } from '../../components/Widgets'; +import { FB_DOCK_RESERVE } from '../../components/FloatDock'; @ComponentV2 export struct FbTripsPage { @@ -85,6 +86,8 @@ export struct FbTripsPage { } } .width('100%') + // 底部悬浮快捷栏的预留:它浮在内容之上,不留白会压住最后一屏 + .padding({ bottom: FB_DOCK_RESERVE }) } .width('100%') .height('100%')