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

如何在Flutter中实现底部带倒圆角的AppBar

实现底部带倒圆角的AppBar 正确方案

我想要实现底部带倒圆角的AppBar,尝试了以下代码,但认为该实现方法并不正确,希望获取正确的实现方式。

我的尝试代码

Scaffold(
      body: SafeArea(
        child: ListView(
          physics: const BouncingScrollPhysics(),
          children: [
            Stack(
              children: [
                Container(
                  height: 180,
                  decoration: const BoxDecoration(gradient: AppColor.bgColor),
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 140),
                  child: Container(
                    height: MediaQuery.of(context).size.height - 250,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(30),
                      color: Colors.white
                    ),
                  ),
                )
              ],
            ),
          ],
        ),
      ),
    );

问题分析

你当前的实现用Stack嵌套固定高度容器,存在两个核心问题:

  • 高度依赖屏幕尺寸硬编码计算,不同设备上适配容易出错;
  • 整个Stack作为ListView的单个子项,滚动时顶部渐变栏会跟着滚动消失,不符合这类界面顶部栏固定/半固定的常规需求。

正确实现方式

方式一:使用SliverAppBar(支持滚动折叠)

这种方式适合需要顶部栏随滚动折叠的场景,同时自然实现底部圆角:

Scaffold(
  body: CustomScrollView(
    physics: const BouncingScrollPhysics(),
    slivers: [
      // 带底部圆角的渐变顶部栏
      SliverAppBar(
        expandedHeight: 180,
        backgroundColor: Colors.transparent,
        elevation: 0,
        flexibleSpace: FlexibleSpaceBar(
          background: Container(
            decoration: const BoxDecoration(
              gradient: AppColor.bgColor,
              borderRadius: BorderRadius.only(
                bottomLeft: Radius.circular(30),
                bottomRight: Radius.circular(30),
              ),
            ),
            // 可添加标题、图标等内容
            child: const SafeArea(
              child: Padding(
                padding: EdgeInsets.all(16),
                child: Text("顶部标题", style: TextStyle(fontSize: 24, color: Colors.white)),
              ),
            ),
          ),
        ),
      ),
      // 白色内容区域
      SliverToBoxAdapter(
        child: Container(
          color: Colors.white,
          padding: const EdgeInsets.all(16),
          child: Column(
            children: List.generate(20, (index) => ListTile(title: Text("列表项 $index"))),
          ),
        ),
      ),
    ],
  ),
);

方式二:固定高度顶部栏(无滚动折叠)

如果不需要顶部栏滚动折叠,直接用PreferredSize自定义AppBar即可:

Scaffold(
  appBar: PreferredSize(
    preferredSize: const Size.fromHeight(180),
    child: Container(
      decoration: const BoxDecoration(
        gradient: AppColor.bgColor,
        borderRadius: BorderRadius.only(
          bottomLeft: Radius.circular(30),
          bottomRight: Radius.circular(30),
        ),
      ),
      child: const SafeArea(
        child: Center(
          child: Text("固定顶部栏", style: TextStyle(fontSize: 24, color: Colors.white)),
        ),
      ),
    ),
  ),
  body: Container(
    color: Colors.white,
    child: ListView.builder(
      physics: const BouncingScrollPhysics(),
      itemCount: 20,
      itemBuilder: (context, index) => ListTile(title: Text("列表项 $index")),
    ),
  ),
);

这两种方式都能完美实现底部带倒圆角的顶部栏,且适配性更好,滚动逻辑更合理。

内容的提问来源于stack exchange,提问作者mishalhaneef

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:47:42