Francesco Romano
Francesco Romano

Reputation: 699

Flutter how to handle image with fixed size inside box?

I am new to Flutter and I like it but I am not comfortable building layouts.

I am working on an app that contains a ListView of Cards. Each card is inside a Container and contains an image (with fixed height and width) and a text.

I am not able to place the image correctly inside the Card. I want the image to cover the width of box. Thanks.

enter image description here

This is the code:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'MyApp';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: ListView(
          children: <Widget>[
              Container(
                    margin:EdgeInsets.all(8.0),
                    child: Card(
                        shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
                        child: InkWell(
                           onTap: () => print("ciao"),     
                           child: Column(
                                children: <Widget>[
                                    ClipRRect(
                                      borderRadius: BorderRadius.only(
                                        topLeft: Radius.circular(8.0),
                                        topRight: Radius.circular(8.0),
                                      ),
                                      child: Image.asset(
                                        'img/britannia.jpg',
                                        width: 300,
                                        height: 150,
                                        fit:BoxFit.fill  

                                      ),
                                    ),
                                    ListTile(
                                      title: Text('Pub 1'),
                                      subtitle: Text('Location 1'),
                                    ),
                                ],
                           ),
                        ),
                    ),
              ),
          ],
        ),
      ),
    );
  }
} 

Upvotes: 60

Views: 321447

Answers (15)

0xShakhawat
0xShakhawat

Reputation: 31

Add this line in Column

crossAxisAlignment: CrossAxisAlignment.stretch,

It will work fine

Upvotes: 0

Image Widget will make parent Widget reduce size some how, i think the key is assign width or height of parent Widget (Container or SizedBox) to double.infinity, and you will able to use BoxFit easier.

Upvotes: 0

yobo zorle
yobo zorle

Reputation: 418

Sample;

Image.asset(
                        'assets/img/premium_user.png',
                        fit: BoxFit.contain,
                        height: 20,
                      ),

Then set preferred height.

Upvotes: 1

Nolca
Nolca

Reputation: 55

  1. crossAxisAlignment: CrossAxisAlignment.center,
  2. fit: BoxFit.fitWidth,
  3. width: double.infinity, height: 100,

Example:

Column(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Image.network(userinfo.avatar ?? '',
        fit: BoxFit.fitWidth,
        width: double.infinity,
        height: 100,
        errorBuilder: (context, error, stackTrace) => Image.asset(
              'assets/niko_huh.png',
              fit: BoxFit.fitWidth,
              width: double.infinity,
              height: 100,
            )),

Upvotes: 0

Hardik Hirpara
Hardik Hirpara

Reputation: 3046

Put Image widget inside container and give alignment center to container and specific width-height to the image.

return Container(
      alignment: Alignment.center,// use aligment
      color: Color.fromRGBO(0, 96, 91, 1),
      child: Image.asset('assets/images/splash_logo.png',
        height: 150,
        width: 150,
      fit: BoxFit.cover),
    );

Upvotes: 19

Sandeep Pareek
Sandeep Pareek

Reputation: 1789

child: Container(
              alignment: Alignment.center,// use aligment
              child: Image.asset(
                'assets/images/call.png',
                height: 45,
                width: 45,
                fit: BoxFit.cover,
              ),
            ),

Use this if you want with border

            Center(
          child: Container(
            margin: EdgeInsets.only(top: 75),
            width: 120,
            height: 120,
            alignment: Alignment.center,
            child: Image.asset(
              "assets/images/call.png",
              fit: BoxFit.cover,
              height: 45,
              width: 45,
            ),
            decoration: new BoxDecoration(
              color: Colors.white,
              borderRadius: new BorderRadius.all(new Radius.circular(120)),
              border: new Border.all(
                color: Colors.blue,
                width: 4.0,
              ),
            ),
          ),
        )

Upvotes: 7

CopsOnRoad
CopsOnRoad

Reputation: 268544

All you need is fit property of Image class:

Image.asset(
  'your_image_asset',
  fit: BoxFit.fill, // Expands to fill parent (changes aspect ratio)
)

or

Image.asset(
  'your_image_asset',
  fit: BoxFit.cover, // Zooms the image (maintains aspect ratio)
)

Upvotes: 4

Riad Rekab
Riad Rekab

Reputation: 129

I had the same problem, I just added in the Image.asset class the fit:BoxFit.fill after using the MediaQuery class to get the width of the screen**

    Container(
              child:Image.asset(link,fit: BoxFit.fill,)
              width: screensize.width,
              height: 150,
            ))

Upvotes: 1

Osama Sandhu
Osama Sandhu

Reputation: 421

 Image.asset(
                  'assets/images/desert.jpg',
                  height: 150,
                  width: MediaQuery.of(context).size.width,
                  fit:BoxFit.cover

              )

Upvotes: 9

Leonardo Rignanese
Leonardo Rignanese

Reputation: 1213

What you want to do is probably use the size of the bigger container. In that case your media should occupy the whole dedicate space:

return Container(
      alignment: Alignment.center,
      height: double.infinity,
      width: double.infinity,
      child: Image.asset(
        '', //TODO fill path
        height: double.infinity,
        width: double.infinity,
        fit: BoxFit.cover,
      ),
    );

You can play with the fit value:

  • BoxFit.cover will cover the whole container
  • BoxFit.fitWidth will fit the width and eventually put horizontal white bars to fill the space
  • BoxFit.fitHeight will fit the height and eventually put vertical white bars to fill the space

Upvotes: 4

Rahul Dange
Rahul Dange

Reputation: 2671

I don't know how.. But this really worked to keep image with fixed size in container Just add Alignment in container

    Container(
      height: double.infinity,
      alignment: Alignment.center, // This is needed
      child: Image.asset(
        Constants.ASSETS_IMAGES + "logo.png",
        fit: BoxFit.contain,
        width: 300,
      ),
    );

Upvotes: 30

Mohamed Assem Ali
Mohamed Assem Ali

Reputation: 43

I used this and worked fine with me!

  Container(
                    width: MediaQuery.of(context).size.width,
                    height: 175,
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        fit: BoxFit.cover,
                        image: NetworkImage(YOUTUBE_THUMBNAIL_PART_ONE +
                            video.key +
                            YOUTUBE_THUMBNAIL_PART_TWO),
                      ),
                    )),

Upvotes: 4

Pedro R.
Pedro R.

Reputation: 673

This worked for me

Image.network(imageUrl, fit: BoxFit.fitWidth,),

Upvotes: 24

anmol.majhail
anmol.majhail

Reputation: 51336

You need to add - crossAxisAlignment: CrossAxisAlignment.stretch, in Column so that children can take up horizontal space.

Working Code:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'MyApp';

return MaterialApp(
  title: title,
  home: Scaffold(
    appBar: AppBar(
      title: Text(title),
    ),
    body: ListView(
      children: <Widget>[
        Container(
          margin:EdgeInsets.all(8.0),
          child: Card(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
            child: InkWell(
              onTap: () => print("ciao"),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,  // add this
                children: <Widget>[
                  ClipRRect(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(8.0),
                      topRight: Radius.circular(8.0),
                    ),
                    child: Image.network(
                        'https://placeimg.com/640/480/any',
                       // width: 300,
                        height: 150,
                        fit:BoxFit.fill

                    ),
                  ),
                  ListTile(
                    title: Text('Pub 1'),
                    subtitle: Text('Location 1'),
                  ),
                ],
              ),
            ),
          ),
        ),
        Container(
          margin:EdgeInsets.all(8.0),
          child: Card(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
            child: InkWell(
              onTap: () => print("ciao"),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  ClipRRect(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(8.0),
                      topRight: Radius.circular(8.0),
                    ),
                    child: Image.network(
                        'https://placeimg.com/640/480/any',
                        // width: 300,
                        height: 150,
                        fit:BoxFit.fill

                    ),
                  ),
                  ListTile(
                    title: Text('Pub 1'),
                    subtitle: Text('Location 1'),
                  ),
                ],
              ),
            ),
          ),
        ),
        Container(
          margin:EdgeInsets.all(8.0),
          child: Card(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
            child: InkWell(
              onTap: () => print("ciao"),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  ClipRRect(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(8.0),
                      topRight: Radius.circular(8.0),
                    ),
                    child: Image.network(
                        'https://placeimg.com/640/480/any',
                        // width: 300,
                        height: 150,
                        fit:BoxFit.fill

                    ),
                  ),
                  ListTile(
                    title: Text('Pub 1'),
                    subtitle: Text('Location 1'),
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    ),
      ),
    );
  }
}

output:

enter image description here

Upvotes: 63

Ferdi
Ferdi

Reputation: 788

If doable with the fit property, I let this very clear cheat sheet (chapter fit Property) detail everything: https://medium.com/jlouage/flutter-boxdecoration-cheat-sheet-72cedaa1ba20

Upvotes: 3

Related Questions