206
votes

I am trying to set a background image for the home page. I am getting the image place from start of the screen and filling the width but not the height. Am I missing something in my code? Are there image standards for flutter? Do images scale based on each phone's screen resolution?

class BaseLayout extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return new Scaffold(
      body: new Container(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            new Image.asset("assets/images/bulb.jpg") 
          ]
        )
      )
    );
  }
}
13
what should be the size of the image? width*height?ArgaPK
Can somebody give an example with network image callThe Billionaire Guy
@TheDeadGuy Image.network('example.com/path/to/image.jpg')?SacWebDeveloper
checkout solution here on this link stackoverflow.com/a/62245570/9955978Shubham Sharma

13 Answers

513
votes

I'm not sure I understand your question, but if you want the image to fill the entire screen you can use a DecorationImage with a fit of BoxFit.cover.

class BaseLayout extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/bulb.jpg"),
            fit: BoxFit.cover,
          ),
        ),
        child: null /* add child content here */,
      ),
    );
  }
}

For your second question, here is a link to the documentation on how to embed resolution-dependent asset images into your app.

61
votes

If you use a Container as the body of the Scaffold, its size will be accordingly the size of its child, and usually that is not what you want when you try to add a background image to your app.

Looking at this other question, @collin-jackson was also suggesting to use Stack instead of Container as the body of the Scaffold and it definitely does what you want to achieve.

This is how my code looks like

@override
Widget build(BuildContext context) {
  return new Scaffold(
    body: new Stack(
      children: <Widget>[
        new Container(
          decoration: new BoxDecoration(
            image: new DecorationImage(image: new AssetImage("images/background.jpg"), fit: BoxFit.cover,),
          ),
        ),
        new Center(
          child: new Text("Hello background"),
        )
      ],
    )
  );
}
28
votes

Screenshot:

enter image description here


Code:

@override
Widget build(BuildContext context) {
  return DecoratedBox(
    decoration: BoxDecoration(
      image: DecorationImage(image: AssetImage("your_asset"), fit: BoxFit.cover),
    ),
    child: Center(child: FlutterLogo(size: 300)),
  );
}
16
votes

You can use Stack to make the image stretch to the full screen.

Stack(
        children: <Widget>
        [
          Positioned.fill(  //
            child: Image(
              image: AssetImage('assets/placeholder.png'),
              fit : BoxFit.fill,
           ),
          ), 
          ...... // other children widgets of Stack
          ..........
          .............
         ]
 );

Note: Optionally if are using a Scaffold, you can put the Stack inside the Scaffold with or without AppBar according to your needs.

9
votes

I was able to apply a background below the Scaffold (and even it's AppBar) by putting the Scaffold under a Stack and setting a Container in the first "layer" with the background image set and fit: BoxFit.cover property.

Both the Scaffold and AppBar has to have the backgroundColor set as Color.transparent and the elevation of AppBar has to be 0 (zero).

Voilà! Now you have a nice background below the whole Scaffold and AppBar! :)

import 'package:flutter/material.dart';
import 'package:mynamespace/ui/shared/colors.dart';
import 'package:mynamespace/ui/shared/textstyle.dart';
import 'package:mynamespace/ui/shared/ui_helpers.dart';
import 'package:mynamespace/ui/widgets/custom_text_form_field_widget.dart';

class SignUpView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack( // <-- STACK AS THE SCAFFOLD PARENT
      children: [
        Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage("assets/images/bg.png"), // <-- BACKGROUND IMAGE
              fit: BoxFit.cover,
            ),
          ),
        ),
        Scaffold(
          backgroundColor: Colors.transparent, // <-- SCAFFOLD WITH TRANSPARENT BG
          appBar: AppBar(
            title: Text('NEW USER'),
            backgroundColor: Colors.transparent, // <-- APPBAR WITH TRANSPARENT BG
            elevation: 0, // <-- ELEVATION ZEROED
          ),
          body: Padding(
            padding: EdgeInsets.all(spaceXS),
            child: Column(
              children: [
                CustomTextFormFieldWidget(labelText: 'Email', hintText: 'Type your Email'),
                UIHelper.verticalSpaceSM,
                SizedBox(
                  width: double.maxFinite,
                  child: RaisedButton(
                    color: regularCyan,
                    child: Text('Finish Registration', style: TextStyle(color: white)),
                    onPressed: () => {},
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}
7
votes

We can use Container and mark its height as infinity

body: Container(
      height: double.infinity,
      width: double.infinity,
      child: FittedBox(
        fit: BoxFit.cover,
        child: Image.network(
          'https://cdn.pixabay.com/photo/2016/10/02/22/17/red-t-shirt-1710578_1280.jpg',
        ),
      ),
    ));

Output:

enter image description here

3
votes
decoration: BoxDecoration(
      image: DecorationImage(
        image: ExactAssetImage("images/background.png"),
        fit: BoxFit.cover
      ),
    ),

this also works inside a container.

3
votes

To set a background image without shrinking after adding the child, use this code.

  body: Container(
    constraints: BoxConstraints.expand(),
      decoration: BoxDecoration(
        image: DecorationImage(
            image: AssetImage("assets/aaa.jpg"),
        fit: BoxFit.cover,
        )
      ),

    //You can use any widget
    child: Column(
      children: <Widget>[],
    ),
    ),
3
votes
body: Container(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: AssetImage('images/background.png'),fit:BoxFit.cover
      )
    ),
);
1
votes

You can use FractionallySizedBox

Sometimes decoratedBox doesn't cover the full-screen size. We can fix it by wrapping it with FractionallySizedBox Widget. In this widget we give widthfactor and heightfactor.

The widthfactor shows the [FractionallySizedBox]widget should take _____ percentage of the app's width.

The heightfactor shows the [FractionallySizedBox]widget should take _____ percentage of the app's height.

Example : heightfactor = 0.3 means 30% of app's height. widthfactor = 0.4 means 40% of app's width.

        Hence, for full screen set heightfactor = 1.0 and widthfactor = 1.0

Tip: FractionallySizedBox goes well with the stack widget. So that you can easily add buttons, avatars, texts over your background image in the stack widget whereas in rows and columns you cannot do that.

For more info check out this project's repository github repository link for this project

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Stack(
            children: <Widget>[
              Container(
                child: FractionallySizedBox(
                  heightFactor: 1.0,
                  widthFactor: 1.0,
                  //for full screen set heightFactor: 1.0,widthFactor: 1.0,
                  child: DecoratedBox(
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        image: AssetImage("images/1.jpg"),
                        fit: BoxFit.fill,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}



OutPut: enter image description here

1
votes
import 'package:flutter/material.dart';

void main() => runApp(DestiniApp());

class DestiniApp extends StatefulWidget {
  @override
  _DestiniAppState createState() => _DestiniAppState();
}

class _DestiniAppState extends State<DestiniApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SafeArea(
        child: Scaffold(
          appBar: AppBar(
            backgroundColor: Color.fromRGBO(245, 0, 87, 1),
            title: Text(
              "Landing Page Bankground Image",
            ),
          ),
          body: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                  image: ExactAssetImage("images/appBack.jpg"),
                  fit: BoxFit.cover
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Output: enter image description here

0
votes

You can use the following code to set a background image to your app:

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage("images/background.jpg"),
            fit: BoxFit.cover,
          ),
        ),
        // use any child here
        child: null
      ),
    );
  }

If your Container's child is a Column widget, you can use the crossAxisAlignment: CrossAxisAlignment.stretch to make your background image fill the screen.

0
votes

Other answers are great. This is another way it can be done.

  1. Here I use SizedBox.expand() to fill available space and for passing tight constraints for its children (Container).
  2. BoxFit.cover enum to Zoom the image and cover whole screen
 Widget build(BuildContext context) {
    return Scaffold(
      body: SizedBox.expand( // -> 01
        child: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: NetworkImage('https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
              fit: BoxFit.cover,    // -> 02
            ),
          ),
        ),
      ),
    );
  }

screenshot