Search code examples
user-interfaceflutterdartappbar

How to prevent AppBar from covering the background?


I'm trying to implement a custom AppBar using a PreferredSize and a Card widget. Here is the result:

enter image description here

However, when I scroll down a bit, the AppBar layout is covering the background (which is the body part of the scaffold) like this:

enter image description here

See second screenshot: The custom AppBar is covering everything that goes under it. Is there a way to prevent this?

By the way, these sample images came from a StreamBuilder widget attached to the body of the Scaffold.

Here is the code:

appBar: PreferredSize(
        preferredSize: Size.fromHeight(50.0),
        child: SizedBox(
          height: 100.0,
          child: Card(
            elevation: 10.0,
            color: Colors.white.withOpacity(0.8),
            clipBehavior: Clip.antiAlias,
            margin: EdgeInsets.only(top: 30.0, left: 10.0, right: 10.0),
            child: Stack(
              children: <Widget>[
                GestureDetector(
                  onTap: () {
                    _key.currentState.openDrawer();
                  },
                  child: Padding(
                    padding: const EdgeInsets.only(top: 9.0, left: 10.0),
                    child: Icon(FontAwesomeIcons.bars, color: Colors.grey[800]),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 13.0, left: 50.0),
                  child: TextField(
                    decoration: InputDecoration.collapsed(
                      hintText: 'Search... ',
                      hintStyle: TextStyle(fontFamily: 'Monospace')
                    ),
                  ),
                ),
                GestureDetector(
                  onTap: () {
                    _key.currentState.openEndDrawer();
                  },
                  child: Padding(
                    padding: const EdgeInsets.only(top: 9.0, left: 305.0),
                    child: Icon(FontAwesomeIcons.slidersH, color: Colors.grey[800]),
                  ),
                )
              ],
            ),
          ),
        )
      ),

Thanks for your answers!


Solution

  • Instead of setting your PreferredSize appbar directly to the appBar property of the Scaffold, rather Stack it within the body. This code should work for your desired outcome.

    Scaffold(
      body: Stack(
        children: [
          Container(), // this is where your main body goes
          Positioned(
            top: 30,
            left: 10,
            right: 10,
            child: PreferredSize(
              preferredSize: Size.fromHeight(25.0),
              child: Container(
                color: Colors.white.withOpacity(0.0),
                height: 50.0,
                child: Card(
                  elevation: 10.0,
                  color: Colors.white.withOpacity(1),
                  clipBehavior: Clip.antiAlias,
                  child: Stack(
                    children: <Widget>[
                      GestureDetector(
                        onTap: () {
                          _key.currentState.openDrawer();
                        },
                        child: Padding(
                          padding: const EdgeInsets.only(top: 9.0, left: 10.0),
                          child: Icon(Icons.menu, color: Colors.grey[800]),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(top: 13.0, left: 50.0),
                        child: TextField(
                          decoration: InputDecoration.collapsed(
                            hintText: 'Search... ',
                            hintStyle: TextStyle(fontFamily: 'Monospace')
                          ),
                        ),
                      ),
                      GestureDetector(
                        onTap: () {                            
                          _key.currentState.openEndDrawer();
                        },
                        child: Padding(
                          padding: const EdgeInsets.only(top: 9.0, left: 305.0),
                          child: Icon(Icons.star, color: Colors.grey[800]),
                        ),
                      )
                    ],
                  ),
                ),
              )
            ),
          ),
        ]
      ),
    );
    

    Sample out come:

    Default Scrolled