Flutter Why is container width not honoured?

Viewed 14672

I'm trying to create a circle image. Unfortunately, the width of the container is not honoured and I can't figure out why. What am I missing?

enter image description here

Drawer _getDrawer(List<Job> data) {
  return Drawer(
    // Add a ListView to the drawer. This ensures the user can scroll
    // through the options in the Drawer if there isn't enough vertical
    // space to fit everything.
    child: ListView(
      // Important: Remove any padding from the ListView.
      padding: EdgeInsets.zero,
      children: <Widget>[
        _getDrawerHeader(),
        ListTile(
          title: Text('Item 1'),
          onTap: () {
            // Update the state of the app
            // ...
          },
        ),
        ListTile(
          title: Text('Item 2'),
          onTap: () {
            // Update the state of the app
            // ...
          },
        ),
      ],
    ),
  );
}

DrawerHeader _getDrawerHeader() {
  return DrawerHeader(
    child: StreamBuilder(
        stream: FirebaseAuth.instance.currentUser().asStream(),
        builder: (context, AsyncSnapshot<FirebaseUser> snapshot) {
          if (snapshot.hasData) {
            return ListView(
              children: <Widget>[
                _getCircleImage(snapshot.data.photoUrl),
                Text('test'),
                Text('test'),
              ],
            );
          }
          return Center(child: CircularProgressIndicator());
        }),
    decoration: BoxDecoration(
      color: Colors.blue,
    ),
  );
}

_getCircleImage(String url) {
  return Container(
    width: 64.0,
    height: 64.0,
    decoration: new BoxDecoration(
      image: new DecorationImage(
        image: new NetworkImage(url),
        fit: BoxFit.cover,
      ),
      shape: BoxShape.circle,
    ),
  );
}
3 Answers

That's a little tricky but it's how Flutter works, your Container doesn't know the constraints of the Parent, then It try to fill all the space available.

You can fix it adding an Align Widget

    _getCircleImage(String url) {
      return Align(
        alignment: Alignment.centerLeft,
        child: Container(
          width: 64.0,
          height: 64.0,
          decoration: new BoxDecoration(
            image: new DecorationImage(
              image: new NetworkImage(url),
              fit: BoxFit.cover,
            ),
            shape: BoxShape.circle,
          ),
        ),
      );
    }

More info : https://docs.flutter.io/flutter/widgets/Container-class.html

  • A widget can decide its own size only within the constraints given to it by its parent. This means a widget usually can’t have any size it wants.

  • A widget can’t know and doesn’t decide its own position on the screen, since it’s the widget’s parent who decides the position of the widget.

  • The parent widget takes the entire space available to draw the widget, Here Container is the parent widget, and it's taking whatever space is available, so to give heigh/width to the Container, that needed to be placed inside any widget which assigns x,y position of widgets to get it to draw.

So as per the above description, Container should have a parent that aligns Container on the screen.

Ex: Use

  Align(
     alignment: Alignment.center,
     child: Container(),
  );

OR

 Center(
      child: Container(),
    );

Problem:

Container's constraints wont' have any impact if the passed constraints were tight.

For example:

SizedBox.fromSize(
  size: Size.fromRadius(100), // Tight constraints are passed to the Container below
  child: Container(
    width: 100, // No impact
    height: 100, // No impact
    color: Colors.blue,
  ),
)

Solutions:

You need to loose those tight constraints. There are multiple ways of doing it. I'm listing a few here:

  1. Use UnconstrainedBox:

    SizedBox.fromSize(
      size: Size.fromRadius(100),
      child: UnconstrainedBox( // <-- UnconstrainedBox
        child: Container(
          width: 100, // Works
          height: 100, // Works
          color: Colors.blue,
        ),
      ),
    )
    
  2. Use Center or Align:

    SizedBox.fromSize(
      size: Size.fromRadius(100),
      child: Center( //    <-- Center
        child: Container(
          width: 100, // Works
          height: 100, // Works
          color: Colors.blue,
        ),
      ),
    )
    
  3. Use a Column or better Wrap:

    SizedBox.fromSize(
      size: Size.fromRadius(100),
      child: Wrap( //   <-- Wrap
        children: [
          Container(
            width: 100, // Works
            height: 100, // Works
            color: Colors.blue,
          ),
        ],
      ),
    )
    
Related