v0.6.0 图标改为开抽屉入口 + 新增底部悬浮快捷栏(照鸿蒙 6 悬浮导航规范)

用户 2026-10-12 三条要求。

## ① 点顶栏图标 = 开抽屉
用户:「把那个图标改成这个功能吧,就是当用户点击左上角那个图标的时候,把抽屉列出来」。
⇒ `TopBar` 的 logo 加 `.onClick { drawerOpen = true }`。
⚠️ 点击直接挂在 Image 上、**不套 Button** —— Button 自带最小尺寸与内边距,
会把图标挤离左边线(用户要"图标靠左")。
⇒ 开抽屉现有三个入口:点图标 / 应用内水平滑动 / 底部悬浮栏。

## ② 底部悬浮快捷栏 FbFloatDock(新增)
用户:「页面正下方设置几个浮动按钮…比如日程、名册、任务和笔记…
        这样用户不用拉抽屉,就可以直接点击使用。
        但一定要注意,使用浮动的方式,**不要固定在下面**,而是**浮动着的**。」

🔴 **形态照鸿蒙 6 官方设计规范的「悬浮导航(Float Navigation)」**:
「导航栏脱离底部边界,以**四周留白、圆角卡片**形态悬浮于内容之上」。
参考实现参数直接用上:`height(56) + margin({left:16,right:16,bottom:16})
+ borderRadius(28)`,材质用系统沉浸材质
`uiMaterial.ImmersiveMaterial({ style: ULTRA_THIN })`(设计规范的"超薄"档)。
⚠️ 用了 systemMaterial 就不再叠加 backgroundBlurStyle/backgroundColor ——
   材质自带模糊+边框+阴影,叠加会双重模糊发灰。

⚠️ **摆法关键**:`Index` 的根容器从 `Column` 改成
`Stack({ alignContent: Bottom })` —— 写在 Column 里它就是"占一行的固定底栏"
(老样式);用 Stack 覆盖 ⇒ 内容从它下面穿过、它浮在上面。
(实测印证:栏体 y=2132..2307,而"我的家人"标题在 y=2336 仍可见 ⇒ 内容穿过去了。)

⚠️ 内容底部加 `FB_DOCK_RESERVE`(88vp) 预留,否则最后一屏内容会被悬浮栏压住。
12 个页面统一处理。
⚠️ 宽屏不显示(抽屉常驻,且屏宽用不上);抽屉展开时也不显示(避免浮层叠浮层)。
⚠️ 选中项用模块主题色高亮,用户一眼知道"我在哪"。

## 验证(真机,全部通过)
· 点顶栏图标 ⇒ 抽屉打开 ✓
· 点悬浮栏「任务」⇒ 切到任务页 ✓;点「日程」⇒ 切到日程页 ✓
· 悬浮栏几何:栏体 x=21..1060、y=2132..2307(高 58vp),
  栏外 x=0..20 为纸色 ⇒ **四周留白** 符合规范 ✓
· 栏内呈半透材质色(#EFEBE2) ⇒ `ImmersiveMaterial` 生效 ✓
· 14 页遍历 **14/14**;深验 **12/12**;编译 **0 error / 0 warning**

## 过程中的一个坑
给 12 个页面补 `FB_DOCK_RESERVE` 的 import 时,脚本统一写成
`'../components/FloatDock'` —— 但**页面在 `pages/<模块>/` 下,需要 `../../`**
(`Index.ets` 在 `pages/` 下才是 `../`)。批量改 import 路径要按**文件深度**区分。
This commit is contained in:
2026-10-12 12:06:00 +08:00
parent 705a65ae2e
commit 7eaa641437
15 changed files with 215 additions and 18 deletions
+145
View File
@@ -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';
}
}
}
+15 -8
View File
@@ -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('家书')
+19 -10
View File
@@ -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])
}
@@ -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%')
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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%')
@@ -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%')
@@ -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%')
@@ -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%')
@@ -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%')
@@ -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%')
@@ -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%')