How do I stretch an image to fit the whole background (100% height x 100% width) in Flutter?
Asked Answered
C

19

143

I have an image that doesn't match the aspect ratio of my device's screen. I want to stretch the image so that it fully fills the screen, and I don't want to crop any part of the image.

CSS has the concept of percentages, so I could just set height and width to 100%. But it doesn't seem like Flutter has that concept, and it's bad to just hard code the height and width, so I'm stuck.

Here's what I have (I'm using a Stack since I have something in the foreground of the image):

Widget background = new Container(
  height: // Not sure what to put here!
  width: // Not sure what to put here!
  child: new Image.asset(
    asset.background,
    fit: BoxFit.fill, // I thought this would fill up my Container but it doesn't
  ),
);

return new Stack(
  children: <Widget>[
    background,
    foreground,
  ],
);
Coel answered 17/8, 2017 at 21:49 Comment(0)
E
173

To make an Image fill its parent, simply wrap it into a FittedBox:

FittedBox(
  child: Image.asset('foo.png'),
  fit: BoxFit.fill,
)

FittedBox here will stretch the image to fill the space. (Note that this functionality used to be provided by BoxFit.fill, but the API has meanwhile changed such that BoxFit no longer provides this functionality. FittedBox should work as a drop-in replacement, no changes need to be made to the constructor arguments.)


Alternatively, for complex decorations you can use a Container instead of an Image – and use decoration/foregroundDecoration fields.

To make the Container will its parent, it should either:

  • have no child
  • have alignment property not null

Here's an example that combines two images and a Text in a single Container, while taking 100% width/height of its parent:

enter image description here

Container(
  foregroundDecoration: const BoxDecoration(
    image: DecorationImage(
        image: NetworkImage(
            'https://p6.storage.canalblog.com/69/50/922142/85510911_o.png'),
        fit: BoxFit.fill),
  ),
  decoration: const BoxDecoration(
    image: DecorationImage(
        alignment: Alignment(-.2, 0),
        image: NetworkImage(
            'http://www.naturerights.com/blog/wp-content/uploads/2017/12/Taranaki-NR-post-1170x550.png'),
        fit: BoxFit.cover),
  ),
  alignment: Alignment.bottomCenter,
  padding: EdgeInsets.only(bottom: 20),
  child: Text(
    "Hello World",
    style: Theme.of(context)
        .textTheme
        .display1
        .copyWith(color: Colors.white),
  ),
),
Eicher answered 20/8, 2017 at 12:11 Comment(4)
How can I a add a fade in image widget here? I don't think we can.Sublingual
Ty, I have I think newer version and I did: SizedBox.expand(child: Image.asset("assets/bg.png", fit: BoxFit.fill))Clo
so why is the fit parameter still present in the various Image constructors? What's the use, if it has been de facto replaced by FittedBox?Thrifty
For me, it didn't work with FittedBox. But @Clo 's comment to use SizedBox.expand() did work for me. ThanksBunnell
W
132

The following will fit the image to 100% of container width while the height is constant. For local assets, use AssetImage

Container(
  width: MediaQuery.of(context).size.width,
  height: 100,
  decoration: BoxDecoration(
    image: DecorationImage(
      fit: BoxFit.fill,
      image: NetworkImage("https://picsum.photos/250?image=9"),
    ),
  ),
)

Image fill modes:

  • Fill - Image is stretched

    fit: BoxFit.fill
    

    enter image description here


  • Fit Height - image kept proportional while making sure the full height of the image is shown (may overflow)

    fit: BoxFit.fitHeight
    

    enter image description here


  • Fit Width - image kept proportional while making sure the full width of the image is shown (may overflow)

    fit: BoxFit.fitWidth
    

    enter image description here


  • Cover - image kept proportional, ensures maximum coverage of the container (may overflow)

    fit: BoxFit.cover
    

    enter image description here


  • Contain - image kept proportional, minimal as possible, will reduce it's size if needed to display the entire image

    fit: BoxFit.contain
    

    enter image description here

Womack answered 20/1, 2019 at 12:17 Comment(4)
Never use MediaQuery to make an widget fill its parent. That's not what you wantGridley
@RémiRousselet can you explain reason for that (or give me a link to that reason) .Thanks.Divulsion
I will go with "fit: BoxFit.cover,". Thanks.Rakes
This deserves an extra up-vote for the awesome examples of each of the fit modes.Mylohyoid
C
71

Inside your Stack, you should wrap your background widget in a Positioned.fill.

return new Stack(
  children: <Widget>[
    new Positioned.fill(
      child: background,
    ),
    foreground,
  ],
);
Coel answered 17/8, 2017 at 21:51 Comment(1)
thanks for this Stack widget overlay, I were searching for this widget in Flutter, by using this it is possible for me to Show Container above Image, cheers!Restrainer
T
46

For me, to develop for web, works fine the following:

Image(
  image: AssetImage('lib/images/portadaSchamann5.png'),
  alignment: Alignment.center,
  height: double.infinity,
  width: double.infinity,
  fit: BoxFit.fill,
),
Tribute answered 24/2, 2021 at 17:38 Comment(1)
this seems to be canon too: SizedBox.expand uses double.infinity for its values too.Slimsy
D
20

Might not be exactly what the OP was looking for, but this page is where I found myself after looking for the problem, so sharing this for everyone with similar issue :)

Stack's fit property did the trick for my needs. Otherwise Image inside (OctoImageIn my case) was padded and providing other Image.fit values did not give any effect.

Stack(
  fit: StackFit.expand, 
  children: [
    Image(
      image: provider,
      fit: BoxFit.cover,
    ),
    // other irrelevent children here
  ]
);
Dispirit answered 14/11, 2020 at 19:19 Comment(0)
L
12

Your Question contains the first step, but you need width and height. you can get the width and height of the screen. Here is a small edit

//gets the screen width and height
double Width = MediaQuery.of(context).size.width;
double Height = MediaQuery.of(context).size.height;

Widget background = new Image.asset(
  asset.background,
  fit: BoxFit.fill,
  width: Width,
  height: Height,
);

return new Stack(
  children: <Widget>[
    background,
    foreground,
  ],
);

You can also use Width and Height to size other objects based on screen size.

ex: width: Height/2, height: Height/2 //using height for both keeps aspect ratio

Loxodrome answered 8/6, 2019 at 13:50 Comment(1)
fit: BoxFit.fill, on Image was a life saver, thanks :)Kubiak
P
8

The best example for this question I found on this page: https://flutterbeads.com/set-background-image-in-flutter/

By using BoxDecoration and DecorationImage:

Container(
  constraints: BoxConstraints.expand(),
  decoration: const BoxDecoration(
    image: DecorationImage(
        image: AssetImage("assets/images/cat2.jpg"), 
        fit: BoxFit.cover),
  )
Papist answered 22/2, 2022 at 5:58 Comment(0)
C
7

I think that for your purpose Flex could work better than Container():

new Flex(
    direction: Axis.vertical,
    children: <Widget>[
      Image.asset(asset.background)
    ],
   )
Cavorelievo answered 6/8, 2018 at 14:16 Comment(1)
You just saved my life - :) Perfect for me.Stopper
I
5

This should work,

Image.asset('assets/bg.jpg',fit: BoxFit.cover,),
Inappetence answered 28/6, 2021 at 9:13 Comment(1)
This. You can also BoxFit.fitWidth, fitHeight and others.Cascade
S
4

None of the above answers worked for me. And since there is no accepted answer, I found the following extended my image from horizontal edge to horizontal edge:

Container ( width: MediaQuery
                    .of(context)
                    .size
                    .width,
                child: 
                  Image.network(my_image_name, fit: BoxFit.fitWidth )
              )
Schaerbeek answered 11/5, 2020 at 15:34 Comment(1)
This answer works when you only want to fit the image to full width without stretching itTrilley
C
4

Visit https://youtu.be/TQ32vqvMR80 OR

For example if parent contrainer has height: 200, then

Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                image: NetworkImage('url'),
                fit: BoxFit.cover,
              ),
            ),
          ),
Compliancy answered 6/9, 2020 at 10:34 Comment(0)
U
3

For filling, I sometimes use SizedBox.expand

Unprecedented answered 12/10, 2018 at 21:34 Comment(0)
A
3

I set width and height of a container to double.infinity like so:

Container(
        width: double.infinity,
        height: double.infinity,
        child: //your child
)
Abductor answered 21/12, 2020 at 19:21 Comment(1)
This won't work for the child of the container, just the container.Shakta
V
3

This will work if you want to add a fit background image in Flutter:

class Myname extends StatelessWidget {
  const Myname({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: Container(
          decoration: const BoxDecoration(
            image: DecorationImage(
              image: AssetImage("assets/aj.jpg"),
              fit: BoxFit.cover,
            ),
          ),
          child: Scaffold(
            backgroundColor: Colors.transparent,
            body: Column(),
          ),
        ),
      ),
    );
  }
}

Now you can add the rest of the things inside the Column()

Vitebsk answered 9/9, 2022 at 8:36 Comment(0)
F
2

I ran into problems with just an FittedBox so I wrapped my Image in an LayoutBuilder:

LayoutBuilder( 
   builder: (_, constraints) => Image(
      fit: BoxFit.fill,
      width: constraints.maxWidth,
      image: AssetImage(assets.example),
   ),
)

This worked like a charm and I suggest you give it a try.
Of course you can use height instead of width, this is just what I used.

Fain answered 7/1, 2021 at 12:19 Comment(0)
B
1

For me, using Image(fit: BoxFit.fill ...) worked when in a bounded container.

Baroque answered 19/5, 2020 at 19:59 Comment(0)
E
1

This worked for me

class _SplashScreenState extends State<SplashScreen> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: FittedBox(
        child: Image.asset("images/my_image.png"),
        fit: BoxFit.fill,
      ),);
  }
}
Eternal answered 22/9, 2020 at 11:29 Comment(0)
S
1

I didn’t find answer in this post, But I found the fix:

        Positioned(
            bottom: 0,
            top: 0,
            child: Image.asset(
          'assets/images/package_bg.png',
        )),

This code make image fit to height on the stack.

Storekeeper answered 22/12, 2021 at 14:6 Comment(0)
S
0

Try setting contentPadding

ListTile(
  contentPadding: EdgeInsets.all(0.0),
  ...
)
Struggle answered 6/6, 2019 at 9:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.