You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现搜索框跨AppBar与Body区域显示的方案

解决AppBar与Body间悬浮搜索框的显示问题

我在Flutter应用中实现了带渐变背景的AppBar,Body部分用Expanded包裹了列表组件。想要在AppBar和Body之间放置一个悬浮的搜索框,但使用Stack布局时,超出AppBar或Body范围的部分无法显示出来。

以下是我的原始代码:

appBar: PreferredSize(
        preferredSize: const Size.fromHeight(100),
        child: Stack(
          children: [
            AppBar(
              backgroundColor: Colors.transparent,
              flexibleSpace: Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(25),
                  gradient: LinearGradient(
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                    colors: [
                      Theme.of(context).colorScheme.secondary,
                      Theme.of(context).colorScheme.primary,
                    ],
                    stops: const [
                      0.0,
                      0.69,
                    ],
                  ),
                ),
              ),
              title: Text(
                title,
                style: TextStyle(
                  shadows: [
                    Shadow(
                      color: tonsDeAzul[12],
                      offset: const Offset(0, -8),
                    ),
                  ],
                  color: Colors.transparent,
                  decoration: TextDecoration.underline,
                  decorationColor: tonsDeAzul[12],
                  decorationThickness: 3,
                ),
              ),
              centerTitle: false,
              automaticallyImplyLeading: false,
              actions: [
                Padding(
                  padding: const EdgeInsets.only(right: 5.0),
                  child: TextButton(
                    child: Icon(
                      Icons.comment_outlined,
                      color: tonsDeAzul[12],
                    ),
                    onPressed: () {
                      print("Open messages");
                    },
                  ),
                )
              ],
            ),
            Positioned(
              bottom: -25,
                left: 20,
                right: 20,
                child: StandardSearch(
              textController: _searchController,
              label: "Pesquisar por palavra ou código",
              onSubmit: () {},
            ))
          ],
        ),
      ),
body: Container(
        color: Theme.of(context).colorScheme.surfaceVariant,
        child: clients != null
            ? Column(
                children: [
                  Padding(
                    padding: const EdgeInsets.symmetric(
                      vertical: 24,
                      horizontal: 16,
                    ),
                    child: StandardSearch(
                      textController: _searchController,
                      label: "Pesquisar por palavra ou código",
                      onSubmit: () {},
                    ),
                  ),
                  Expanded(
                    child: ListView.builder(
                      itemCount: clients.length,
                      itemBuilder: (context, index) {
                        final item = clients[index];
                        return Padding(
                          padding: const EdgeInsets.only(bottom: 8),
                          child: InkWell(
                            onTap: () {
                              openPedidoDialog(item, cubit);
                            },
                            child: Column(
                              children: [
                                clientCard(item, context),
                                const Divider(),
                              ],
                            ),
                          ),
                        );
                      },
                    ),
                  ),
                ],
              )
            : const Text("Não foi possível encontrar clientes"))

超出区域被隐藏

解决方法

问题出在两个地方:一是AppBar的PreferredSize高度限制了布局范围,超出部分被裁剪;二是Body的顶部没有留出搜索框的空间,导致内容被遮挡。按以下步骤修改:

  1. 调整AppBar的PreferredSize高度
    把原来的Size.fromHeight(100)改为Size.fromHeight(125),预留出搜索框向下偏移的25像素高度,确保搜索框超出AppBar的部分不会被裁剪。

  2. 给Body顶部添加间距
    在Body的Column开头添加一个SizedBox(height: 25),避免列表内容被悬浮的搜索框挡住。同时删除Body里原来的StandardSearch组件,避免重复显示。

修改后的完整代码

appBar: PreferredSize(
  preferredSize: const Size.fromHeight(125), // 调整高度容纳搜索框
  child: Stack(
    children: [
      AppBar(
        backgroundColor: Colors.transparent,
        flexibleSpace: Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(25),
            gradient: LinearGradient(
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: [
                Theme.of(context).colorScheme.secondary,
                Theme.of(context).colorScheme.primary,
              ],
              stops: const [
                0.0,
                0.69,
              ],
            ),
          ),
        ),
        title: Text(
          title,
          style: TextStyle(
            shadows: [
              Shadow(
                color: tonsDeAzul[12],
                offset: const Offset(0, -8),
              ),
            ],
            color: Colors.transparent,
            decoration: TextDecoration.underline,
            decorationColor: tonsDeAzul[12],
            decorationThickness: 3,
          ),
        ),
        centerTitle: false,
        automaticallyImplyLeading: false,
        actions: [
          Padding(
            padding: const EdgeInsets.only(right: 5.0),
            child: TextButton(
              child: Icon(
                Icons.comment_outlined,
                color: tonsDeAzul[12],
              ),
              onPressed: () {
                print("Open messages");
              },
            ),
          )
        ],
      ),
      Positioned(
        bottom: -25,
        left: 20,
        right: 20,
        child: StandardSearch(
          textController: _searchController,
          label: "Pesquisar por palavra ou código",
          onSubmit: () {},
        ))
    ],
  ),
),
body: Container(
  color: Theme.of(context).colorScheme.surfaceVariant,
  child: clients != null
      ? Column(
          children: [
            SizedBox(height: 25), // 给搜索框留出空间
            Expanded(
              child: ListView.builder(
                itemCount: clients.length,
                itemBuilder: (context, index) {
                  final item = clients[index];
                  return Padding(
                    padding: const EdgeInsets.only(bottom: 8),
                    child: InkWell(
                      onTap: () {
                        openPedidoDialog(item, cubit);
                      },
                      child: Column(
                        children: [
                          clientCard(item, context),
                          const Divider(),
                        ],
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        )
      : const Text("Não foi possível encontrar clientes"))

内容的提问来源于stack exchange,提问作者Gustavo F.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:43:21