Make AppBar transparent and show background image which is set to whole screen
Asked Answered
H

13

114

I have added AppBar in my flutter application. My screen already have a background image, where i don't want to set appBar color or don't want set separate background image to appBar.

I want show same screen background image to appBar also.

I already tried by setting appBar color as transparent but it shows color like gray.

Example code:

appBar: new AppBar(
        centerTitle: true,
//        backgroundColor: Color(0xFF0077ED),
        elevation: 0.0,
        title: new Text(
            "DASHBOARD",
            style: const TextStyle(
                color:  const Color(0xffffffff),
                fontWeight: FontWeight.w500,
                fontFamily: "Roboto",
                fontStyle:  FontStyle.normal,
                fontSize: 19.0
            )),
      )

enter image description here

Haemoglobin answered 31/10, 2018 at 9:30 Comment(4)
Grey color because of elevation. You can set AppBar(backgroundColor: Colors.transparent, elevation: 0.0,) and appbar will be transparentAmericanism
@AndreyTurkovsky Tnx but its not showing background image which i set to whole screen. it show white color layerHaemoglobin
Dunno if you are still stuck but I found a workaround in github.com/flutter/flutter/issues/17088. Comment by RyanAfrish7 Remove the appBar from the appBar slot of the Scaffold. Add the appBar into a Stack within the Scaffold's body. Add another Container to fill the screen to the Stack. Add all the components into that Container. That's it. You may now add background blur to the appBar and it works like a charm. Worked for meMckellar
Body extending behind AppBar is now supported by Scaffold. Please see my answer for transparent AppBar with body extending under it.Jannet
R
82

you can use Stack widget to do so. Follow below example.

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Scaffold(
            backgroundColor: Colors.transparent,
            appBar: new AppBar(
              title: new Text(
                "Hello World",
                style: TextStyle(color: Colors.amber),
              ),
              backgroundColor: Colors.transparent,
              elevation: 0.0,
            ),
            body: new Container(
              color: Colors.red,
            ),
          ),
        ],
      ),
    );
  }
}
Reserve answered 31/10, 2018 at 10:22 Comment(6)
@Aegletes Thank you for let me know. now it is working perfectly.Reserve
Still doesn't seem to work as intended, honestly I'm not sure what changed?Spermatocyte
Sorry it was my fault with the backgrounds apparently, thank you for your solution.Spermatocyte
Set Scaffold extendBodyBehindAppBar to true.Anneal
This uses a nested scaffold, which isn't a good practice, @gswierczynski's answer should now be considered the correct one.Alvarado
Set elevation to 0 is really helpful.Touraine
J
295

This is supported by Scaffold now (in stable - v1.12.13+hotfix.5).

  • Set Scaffold extendBodyBehindAppBar to true,
  • Set AppBar elevation to 0 to get rid of shadow,
  • Set AppBar backgroundColor transparency as needed.
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true,
      backgroundColor: Colors.red,
      appBar: AppBar(
//        backgroundColor: Colors.transparent,
        backgroundColor: Color(0x44000000),
        elevation: 0,
        title: Text("Title"),
      ),
      body: Center(child: Text("Content")),
    );
  }
Jannet answered 30/12, 2019 at 17:13 Comment(5)
if you are wondering why this doesn't work for a ListView in the body this is because of the default padding of the ListView. You can adjust that by setting the padding ListView(padding: EdgeInsets.only(top: 0),Tantara
Also it might not work if SafeArea is applied, remove SafeArea .Balderdash
now the appbar items are floating all over the screen..(In ListView)Shashaban
If you don't want to change the elevation, you can also set shadowColor: Colors.transparent so it is completly transparent.Hydrogen
Is it possible to achieve this behavior with a SliverAppBar?Amphiaster
R
82

you can use Stack widget to do so. Follow below example.

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Scaffold(
            backgroundColor: Colors.transparent,
            appBar: new AppBar(
              title: new Text(
                "Hello World",
                style: TextStyle(color: Colors.amber),
              ),
              backgroundColor: Colors.transparent,
              elevation: 0.0,
            ),
            body: new Container(
              color: Colors.red,
            ),
          ),
        ],
      ),
    );
  }
}
Reserve answered 31/10, 2018 at 10:22 Comment(6)
@Aegletes Thank you for let me know. now it is working perfectly.Reserve
Still doesn't seem to work as intended, honestly I'm not sure what changed?Spermatocyte
Sorry it was my fault with the backgrounds apparently, thank you for your solution.Spermatocyte
Set Scaffold extendBodyBehindAppBar to true.Anneal
This uses a nested scaffold, which isn't a good practice, @gswierczynski's answer should now be considered the correct one.Alvarado
Set elevation to 0 is really helpful.Touraine
C
82

You can use Scaffold's property "extendBodyBehindAppBar: true" Don't forget to wrap child with SafeArea

  @Override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          widget.title,
          style: TextStyle(color: Colors.black),
        ),
        backgroundColor: Colors.transparent,
        elevation: 0.0,
      ),
      extendBodyBehindAppBar: true,
      body: Container(
        width: double.infinity,
        height: double.infinity,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('assets/background/home.png'),
            fit: BoxFit.cover,
          ),
        ),
        child: SafeArea(
            child: Center(
          child: Container(
            width: 300,
            height: 300,
            decoration: BoxDecoration(
              color: Colors.green,
            ),
            child: Center(child: Text('Test')),
          ),
        )),
      ),
    );
  }

enter image description here

Chilli answered 24/1, 2020 at 12:33 Comment(0)
A
21

None of these seem to work for me, mine went something like this:

return Scaffold(
  extendBodyBehindAppBar: true,
  appBar: AppBar(
    backgroundColor: Colors.transparent,
    iconTheme: IconThemeData(color: Colors.white),
    elevation: 0.0,
  ),
  body: Stack(
    children: <Widget>[
      Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(
                'https://images.unsplash.com/photo-1517030330234-94c4fb948ebc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1275&q=80'),
            fit: BoxFit.cover,
          ),
        ),
        child: Padding(
          padding: const EdgeInsets.fromLTRB(0, 100, 0, 0),
          child:
          // Column of widgets here...
        ),
       ),
     ],
   ),
 );
Arvo answered 30/8, 2020 at 18:44 Comment(1)
I think there is no need for the "brightness: Brightness.dark,"Wean
D
13

Output:

enter image description here

A lot of answers but nobody explains why extendBodyBehindAppBar works? It works because when we assigned extendBodyBehindAppBar as true, then the body of the widget takes the height of AppBar, and we see an image covering the AppBar area.

Simple Example:

Size size = MediaQuery.of(context).size;
    return Scaffold(
      extendBodyBehindAppBar: true,
      body: Container(
        // height: size.height * 0.3,
        child: Image.asset(
          'shopping_assets/images/Fruits/pineapple.png',
          fit: BoxFit.cover,
          height: size.height * 0.4,
          width: size.width,
        ),
      ),
    );
Dinse answered 30/11, 2020 at 10:10 Comment(0)
G
12

There could be many cases, for example, do you want to keep the AppBar or not, whether or not you want to make the status bar visible, for that, you can wrap Scaffold.body in SafeArea and if you want AppBar to not have any shadow (unlike the red I provided in example 2), you can set its color to Colors.transparent:

  • Full image (without AppBar)

    enter image description here

    Scaffold(
      extendBodyBehindAppBar: true,
      body: SizedBox.expand(
        child: Image.network(
          'https://wallpaperaccess.com/full/3770388.jpg',
          fit: BoxFit.cover,
        ),
      ),
    )
    
  • Full image (with AppBar)

    enter image description here

    Scaffold(
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        shadowColor: Colors.red,
        title: Text('MyApp'),
      ),
      body: SizedBox.expand(
        child: Image.network(
          'https://wallpaperaccess.com/full/3770388.jpg',
          fit: BoxFit.cover,
        ),
      ),
    )
    
Gingivitis answered 4/1, 2022 at 20:56 Comment(1)
in example 2, add elevation: 0, to the AppBarGyrfalcon
T
6
Scaffold(extendBodyBehindAppBar: true);
Toots answered 18/6, 2021 at 17:34 Comment(0)
C
5

that's what I did and it's working

This is supported by Scaffold now (in stable - v1.12.13+hotfix.5).

Set Scaffold extendBodyBehindAppBar to true, Set AppBar elevation to 0 to get rid of shadow, Set AppBar backgroundColor transparency as needed.

Best regards

Checky answered 31/3, 2020 at 7:51 Comment(0)
I
1

In my case I did it as follows:

Additional create an app bar with a custom back button (in this case with a FloatingActionButton). You can still add widgets inside the Stack.

class Home extends StatefulWidget {
  @override
  _EditProfilePageState createState() => _EditProfilePageState();
}

class _HomeState extends State< Home > {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          this._backgroundImage(), // --> Background Image
          Positioned( // --> App Bar
            child: AppBar(
              backgroundColor: Colors.transparent,
              elevation: 0.0,
              leading: Padding( // --> Custom Back Button
                padding: const EdgeInsets.all(8.0),
                child: FloatingActionButton(
                  backgroundColor: Colors.white,
                  mini: true,
                  onPressed: this._onBackPressed,
                  child: Icon(Icons.arrow_back, color: Colors.black),
                ),
              ),
            ),
          ),
          // ------ Other Widgets ------
        ],
      ),
    );
  }

  Widget _backgroundImage() {
    return Container(
      height: 272.0,
      width: MediaQuery.of(context).size.width,
      child: FadeInImage(
        fit: BoxFit.cover,
        image: NetworkImage(
            'https://images.unsplash.com/photo-1527555197883-98e27ca0c1ea?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80'),
        placeholder: AssetImage('assetName'),
      ),
    );
  }

  void _onBackPressed() {
    Navigator.of(context).pop();
  }
}

In the following link you can find more information Link

Itin answered 15/10, 2019 at 12:18 Comment(0)
N
1

don't forget to set foregroundColor attribite to the desired color in order to make the navigation icon and the title visible

Note that the foregroundColor default value is white.

Nonscheduled answered 21/6, 2022 at 12:48 Comment(0)
B
0

You can Try this This code work for me

@override
  Widget build(BuildContext context) {
    _buildContext = context;
    sw = MediaQuery.of(context).size.width;
    sh = MediaQuery.of(context).size.height;

    return new Container(
      child: new Stack(
        children: <Widget>[
          new Container(
            child: Stack(
              children: <Widget>[
                Container(
                  padding: EdgeInsets.all(20.0),
                  decoration: BoxDecoration(image: backgroundImage),
                ),
              ],
            ),
          ),
          new Scaffold(
            backgroundColor: Colors.transparent,
            appBar: new AppBar(
              title: new Text(Strings.page_register),
              backgroundColor: Colors.transparent,
              elevation: 0.0,
              centerTitle: true,
            ),
            body: SingleChildScrollView(
              padding: EdgeInsets.all(20.0),
              physics: BouncingScrollPhysics(),
              scrollDirection: Axis.vertical,
              child: new Form(
                key: _formKey,
                autovalidate: _autoValidate,
                child: FormUI(),
              ),
            ),
          )
        ],
      ),
    );
  }

backgroundImage

DecorationImage backgroundImage = new DecorationImage(
  image: new ExactAssetImage('assets/images/welcome_background.png'),
  fit: BoxFit.cover,
);
Beguin answered 17/12, 2019 at 9:32 Comment(0)
C
0

use stack

  • set background image
    • Another Scaffold()
      • set background color transperant
      • set custom appbar
      • use column with singleChildScrollView or ListView

enter image description here

@override   Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            children: <Widget>[
              backgroundBGContainer(),
              Scaffold(
                backgroundColor: Colors.transparent,
                appBar: appBarWidgetCustomTitle(context: context, titleParam: ""),
                body: SingleChildScrollView(
                  child: Column(
                    children: <Widget>[
                      _spaceWdgt(),
                      Center(
                        child: Stack(
                          children: <Widget>[
                            new Image.asset(
                              "assets/images/user_icon.png",
                              width: 117,
                              height: 97,
                            ),
                          ],
                        ),
                      ),




  Widget backgroundBGContainer() {
      return Container(
        decoration: new BoxDecoration(
            image: new DecorationImage(
              image: new AssetImage("assets/images/ground_bg_image.png"),
              fit: BoxFit.cover,
            ),
            color: MyColor().groundBackColor),
      );
    }
Calida answered 3/7, 2020 at 7:50 Comment(0)
C
0

Tried all the answers, but either it only works on iOS, or they make against scaffold recommendations within scaffold (visit Multiple Scaffolds for each page inside a Flutter App).

The solution is to use SystemChrome.setSystemUIOverlayStyle.

Widget build(BuildContext context) {
    setBrightnessWithoutAppBar(context, AppColors.transparent, Brightness.light); //look this
     return Scaffold(
       extendBodyBehindAppBar: true,
       body: Stack(children: [
         Positioned(
           top: 0,
           child: Container(
             width: MedSize.widthPhysical,
             height: MedSize.heightPhysical * 0.7.byUI(true),
             decoration: const BoxDecoration(
               image: DecorationImage(
                 image: AssetImage('assets/images/jesus/lovesYou.jpg'),
                 fit: BoxFit.fitWidth,
               )

And in some new file you make your method available:

SystemUiOverlayStyle setBrightnessWithoutAppBar(BuildContext context, Color backgroundColor, Brightness brightness) {
  SystemUiOverlayStyle style = SystemUiOverlayStyle(
    statusBarColor: backgroundColor,
    statusBarIconBrightness: brightness,
    statusBarBrightness: brightness,
  );
  SystemChrome.setSystemUIOverlayStyle(style);
  return style;
}

It seems to me that until Flutter version 3.12, using the AppBar on Android, even with height 0, overlaps the body, even with the use of forceMaterialTransparency = true -regarding the use of image, of course.

Chymotrypsin answered 29/8, 2023 at 22:48 Comment(1)
Please don't add the same answer to multiple questions. Answer the best one and flag the rest as duplicates. See Is it acceptable to add a duplicate answer to several questions?Jonquil

© 2022 - 2024 — McMap. All rights reserved.