如何在Scaffold小部件的AppBar下方显示正文而不是下方?

71

我正在使用一个透明的AppBar,并希望将主体内容显示在透明的AppBar之后,而不是下方。 如何实现?


使用 Stack 而不是 Scaffold 怎么样? - najeira
正如 @najeira 所提到的,Scaffold 对于这个问题并没有帮助。使用 Stack,并使 AppBar 的背景透明。 - Dhrumil Shah - dhuma1981
你的使用栈的解决方案是正确的,但如果我尝试添加带有TextField的表单时,它不起作用。错误:找不到Material小部件。TextField小部件需要一个Material小部件的祖先。 - fvisticot
用材料包装栈。 - najeira
8个回答

144
参数extendBodyBehindAppBar如果指定,将扩展主体以包括AppBar的高度。来自Flutter的Scaffold
Scaffold(
    extendBodyBehindAppBar: true,
)

可在Flutter稳定版1.12+中使用

2023年2月更新

这将使AppBar透明,但您将无法点击正文中的tappable小部件。为此,您需要使用AppBar的forceMaterialTransparency参数。

AppBar(
      forceMaterialTransparency: true,
...
)

14
谢谢,使用ListView时,将顶部内边距设置为0即可解决问题。 ListView(padding: EdgeInsets.only(top: 0)) - Sabeer
1
GridView需要相同的设置:GridView(padding: EdgeInsets.only(top: 0)) - Kleber
1
然后:backgroundColor: Colors.transparent - ItSNeverLate

66
将正文放置在 AppBar 下并使 AppBar 透明需要将 Stack 作为正文。 Stack 必须包含 AppBar 而不是 scaffold。
body: Stack(
        children: <Widget>[...]
),

堆栈中的第一项位于底部,后续项在其上方。如果AppBar是透明的,它看起来像是正常工作,但实际上并非如此。将AppBar变为绿色将向您展示原因。

return Scaffold(
      body: Stack(
        children: <Widget>[
          Container(
            color: Colors.blue,
          ),
          AppBar(title: Text('Hello world'),
            backgroundColor: Colors.green,
          )
        ],);

如您所见,AppBar将占用整个屏幕并消耗任何触摸事件。

全屏应用栏

为解决这个问题,请使用Positioned小部件

body: Stack(
        children: <Widget>[
          Container(
            color: Colors.blue,
          ),
          new Positioned(
          top: 0.0,
          left: 0.0,
          right: 0.0,
          child: AppBar(title: Text('Hello world'),
            backgroundColor: Colors.green,
          ),),
        ], )

你会得到这个:

固定的应用栏

现在让AppBar变透明并删除阴影:

body: Stack(
        children: <Widget>[
          Container( //My container or any other widget
            color: Colors.blue,
          ),
          new Positioned( //Place it at the top, and not use the entire screen
          top: 0.0,
          left: 0.0,
          right: 0.0,
          child: AppBar(title: Text('Hello world'),
            backgroundColor: Colors.transparent, //No more green
            elevation: 0.0, //Shadow gone
          ),),
        ], )

透明应用栏,下方是全屏容器

希望这能帮助到您...


我想让Appbar半透明并具有适当的高度,高度应与普通Appbar相同。我想让Appbar半透明并带有一些带Alpha的背景颜色。这可能吗? - Sagar Panwala
@SagarPanwala 可以将背景设置为任何颜色,然后使用 .withOpacity 方法来设置 alpha 值。例如:Color(0xFF00FF77).withOpacity(0.5) 请参考帮助文档 https://api.flutter.dev/flutter/dart-ui/Color/withOpacity.html - Jason
我是想将Transcluent Appbar的Color(0xFF00FF77)设置为AppBar的颜色,并且设置透明度为0.5。如果我将这个颜色应用到AppBar上,用户可能会感觉AppBar的高度很奇怪,就像你回答中所看到的一样。AppBar的高度非常大。 - Sagar Panwala
最后一个是对我有效的,我不需要把它放在堆栈底部。 - Mohamed Saleh

9

从Scaffold中移除appBar,只需在body中设置Stack Widget,然后将AppBar作为最后一个widget包装在Positioned widget中。

注意:其他答案也是正确的。但是这篇文章的目的是为了任何人想要有渐变AppBar背景和浮动在其上方的Card。

enter image description here

 @override
 Widget build(BuildContext context) {
    return Scaffold(
   body: setUserForm()
    );
  }

  Widget setUserForm() {
    return Stack(children: <Widget>[
    // Background with gradient
      Container(
          decoration: BoxDecoration(
              gradient: LinearGradient(
                  begin: Alignment.centerLeft,
                  end: Alignment.bottomCenter,
                  colors: [Colors.red[900], Colors.blue[700]])),
          height: MediaQuery.of(context).size.height * 0.3
        ),
    //Above card
      Card(
          elevation: 20.0,
          margin: EdgeInsets.only(left: 15.0, right: 15.0, top: 100.0),
          child: ListView(
              padding:
              EdgeInsets.only(top: 20.0, left: 20.0, right: 18.0, bottom: 5.0),
              children: <Widget>[
                TextField(),
                TextField()
              ]

        )),
      // Positioned to take only AppBar size 
      Positioned( 
        top: 0.0,
        left: 0.0,
        right: 0.0,
        child: AppBar(        // Add AppBar here only
          backgroundColor: Colors.transparent,
          elevation: 0.0,
          title: Text("Doctor Form"),
        ),
      ),

    ]);
  }


TextField和TextFormField的焦点在此代码中无法正常工作,有什么想法! - Sathish Gadde
你可以发布TextField的样式吗? - Rakesh

5

屏幕截图:

输入图像描述

代码:

如果您想通过使您的AppBar透明来占用整个空间,您还应该将shadowColor设置为透明颜色。

Scaffold(
  extendBodyBehindAppBar: true, // <-- Set this
  appBar: AppBar(
    backgroundColor: Colors.transparent, // <-- this
    shadowColor: Colors.transparent, // <-- and this
  ),
  body: Placeholder(color: Colors.red),
)

4
您可以使用以下代码实现此功能。
return new Scaffold(
  body: new Stack(
    children: <Widget>[
      new Container(
        color: Colors.blue.shade200,
      ),
      new AppBar(
        title: new Text("App bar"),
        backgroundColor: Colors.transparent,
        elevation: 0.0,
      ),
      new Positioned(
        top: 80.0,
        left: 0.0,
        bottom: 0.0,
        right: 0.0,
        //here the body
        child: new Column(
          children: <Widget>[
            new Expanded(
              child: Container(
                color: Colors.grey,
              ),
            )
          ],
        ),
      ),
    ],
  ),
);

Exemplo


1

现在 Scaffold 上有一个新选项 extendBodyBehindAppBar,详情请见此处的 PR

如果它仍然是一个未被识别的参数,请确保您切换到 dev 渠道并运行 flutter upgrade

编辑: 现在已经在稳定渠道上了。


0

过了一段时间,我不知道这是否会帮助任何人,但是...就这样吧。

问题:我想在我的Scaffold主体上有一个渐变背景,但在Android中,AppBar搞砸了一切。

我的解决方案:

Scaffold(
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        title:  Text("AppBar text"),
      ),
      body: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: [
                HexColor.hexToColor("D76984"),
                HexColor.hexToColor("2369C0")
              ]),
        ),
      )
    );

使用 Stack 的其他解决方案也可能有效,但这样整个屏幕的设计都被迫使用 Stack,对我来说比使用其他小部件不够灵敏...但这只是我的看法。


0

如果要将脚手架主体延伸到顶部AppBar后面,请将以下内容添加到您的脚手架中:

extendBodyBehindAppBar: true,

为了将脚手架主体延伸到BottomNavigationBarBottomAppBar后面(这将在您有停靠的FloatingActionButton时改善UI外观),请将以下内容添加到您的脚手架中:

extendBody: true,

enter image description here

如您所见,在我的示例中,这会导致Body扩展到屏幕的底部,因此您需要确保添加间距,以便BottomAppBar不会隐藏UI功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接