SuperAPI AI 工具集

floating-overlay-reserves-its-own-strip

前端与建站

查看项目

更新于 10-17 16:17

技能介绍

用途

该技能用于处理 Jetpack Compose 中一个常见但容易被忽视的布局问题:浮动在滚动列之上的控件(如返回按钮、玻璃图标按钮)在布局树中是滚动内容的同级节点,而不是叠在其上的父节点。因此它不参与任何测量、排列或滚动范围计算,滚动内容必须显式预留出被它覆盖的那一条条带(strip)。

主要能力

技能围绕“浮动控件不预留空间”这一事实,给出可复用的布局模式与排查清单:

  • 用 BoxWithConstraints 同时容纳滚动 Column 与浮动控件,控件通过 align(Alignment.TopStart) 对齐到角落。
  • 在滚动列顶部放置 Spacer(Modifier.height(BACK_BUTTON_STRIP)) 作为预留条带。
  • 说明 BACK_BUTTON_STRIP 应为控件自身偏移量加尺寸(示例中为 8.dp + 48.dp),并刻意不包含状态栏高度,因为滚动列已通过 innerPadding、控件已通过 windowInsetsPadding 各自消费了 inset。
  • 解释浮动也是保持控件可达性的原因:若放在滚动列内,它会随页面滚出屏幕;对于折射或模糊背景的控件,其背景源也必须是同级节点,否则会形成反馈循环。

使用方式

技能以代码示例加陷阱说明的形式呈现。核心结构如下:

BoxWithConstraints(Modifier.fillMaxSize()) {
    Column(Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(innerPadding)) {
        Spacer(Modifier.height(BACK_BUTTON_STRIP))   // 按钮覆盖的条带
        TitleBlock()
        /* … */
    }

    // 列的兄弟节点:对齐而非堆叠,不影响下方任何内容
    GlassIconButton(
        modifier = Modifier
            .align(Alignment.TopStart)
            .windowInsetsPadding(WindowInsets.statusBars)
            .padding(start = 12.dp, top = 8.dp)
            .size(48.dp),
        onClick = onBack,
    )
}

技能还提供一组 grep 命令用于定位候选屏幕、交错查看滚动器与预留、检查命名条带常量的算术、统计固定宽度 Spacer 是否成对出现,并建议通过临时给条带 Spacer 加背景色来验证预留位置,以及在长状态栏设备上检查 inset 是否被错误计入。

适用场景

  • 页面中存在滚动内容,同时有角落对齐的浮动控件。
  • 浮动控件为半透明、玻璃或模糊效果,需要独立背景源。
  • 需要保证浮动控件在滚动过程中始终可达。
  • 多布局分支(窄屏/宽屏、并排滚动器)下需要精确配对预留与控件。

限制与注意事项

技能明确列出多项陷阱:

  • “对齐”意味着控件不影响任何布局,且不会有任何警告;首行内容会落在控件下方,看起来像 padding 缺陷。
  • 不要在容器(Box 或 scaffold)上预留,因为控件也在同一容器内对齐,padding 会连带移动控件,碰撞依旧存在;预留应属于滚动内容。
  • 条带常量是求和,系统 inset 通常不属于其中;两处都计入 inset 会产生恰好一个状态栏高度的空隙,且依赖设备。
  • 每个滚动分支各自预留,且只预留控件覆盖的那一个分支;未被覆盖的分支不应预留,否则会出现空洞。
  • 标题行可作为预留,但需要成对的宽度 Spacer;单个 Spacer 会使标题槽位偏移半个按钮宽度。
  • 用 Box + align(Center) 居中标题会以整个宽度居中,长标题会直接跑到控件下方。
  • 内容从控件下方穿过是设计决策:控件小且半透明时正确,控件不透明且下方内容重要时应改用参与布局的固定栏。
  • 控件不继承 scaffold padding,必须自带 windowInsetsPadding(WindowInsets.statusBars),否则在某些设备上会落到状态栏下。
  • 预留滚走后,控件会落在任意内容上,因此需要自带背景(玻璃、遮罩、填充形状)以保持可读性。
  • 声明顺序与遍历顺序是两回事,需转储语义树或运行无障碍扫描器确认返回控件的朗读顺序。

验证

技能建议滚动到底部再返回,确认控件不移动、静止时没有内容被永久遮挡;给条带 Spacer 临时加背景色检查其是否恰好位于控件下方;在每个布局分支和长状态栏设备上验证;对居中标题形状加载最长标题,检查是否出现单侧省略号。

相关主题包括:stacked-bars-double-consume-window-insets(条带不应重复计入的 inset)、liquid-glass-backdrop(折射控件为何必须是背景源的兄弟节点)、shell-background-is-not-scheme-background(背景源实际绘制的内容)、empty-state-must-keep-its-navigation(控件需在无内容页面中存活)。