kissmycode
kissmycode

Reputation: 63

How to fill background colour with fixed sized grid

I'm trying to layout a 4x4 grid, with text in the centre of each, and a filled background colour, and I can't get the background colour to expand to fill the whole grid square.

This is the UI code:

  body: new Column(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        new Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            new Column(
              children: [
                new Container(
                  color: Colors.pink,
                  child: new Text("Column 1a"),
                )
              ],
            ),
            new Column(
              children: [
                new Text("Column 1b"),
              ],
            ),
          ],
        ),
        new Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            new Column(
              children: [
                new Text("Column 2a"),
              ],
            ),
            new Column(
              children: [
                new Text("Column 2b"),
              ],
            ),
          ],
        ),
      ]),

This is what it looks like: enter image description here

Note: I've tried using Flexible and Expanded to replace Container, but I get an exception:

The following assertion was thrown during performLayout(): RenderFlex children have non-zero flex but incoming height constraints are unbounded.

Upvotes: 4

Views: 5453

Answers (2)

dso
dso

Reputation: 51

Your gridView widget is inside a scaffold. The Scaffold has a body. Define a color for that body.

return Scaffold :
  appBar...
  body : Container (color : Colors.yellow , child : nameGridViewWidget () )

Upvotes: 5

Rémi Rousselet
Rémi Rousselet

Reputation: 276951

The thing is, you're using spaceEvenly as alignment and never forces your cells to take the space possible.

So in the end, your cells take the least amount of space possible => Here, just the size of your text.

You'd have to play with Expanded to fix it. Which I could help you with. But I won't ! [evil laughs]


In your case, there's a much, MUCH easier way to achieve the desired effect. That is GridView.

With GridView you can specify a gridDelegate to have some unique grid rules. One existing gridDelegate is SliverGridDelegateWithFixedCrossAxisCount which ensure that there's a fixed number of columns ; cells will have for width width / columnCount ; and have a custom width/height ratio.

In your case, you want 2 columns and the ratio to be availableWidth / availableHeight so that 4 cells fills the screen, but without overflow.

Now you're asking : Cool, but how do I get availableWidth / availableHeight ?

The answer : LayoutBuilder.

Layout builder basically delegates the rendering to a callback that takes a Constraints as argument. Where that constraint contains the minimum/maximum width/height the widget can have.

=> availableWidth / availableHeight will be constaint.maxWidth / constaint.maxHeight.

The end result will be much more concise and readable ; with the bonus of being easily customizable (change column count, add less/more then 4 cells, ...)

new LayoutBuilder(
  builder: (context, constaint) {
    return new GridView(
      gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        childAspectRatio: constaint.maxWidth / constaint.maxHeight,
      ),
      children: <Widget>[
        new Container(color: Colors.red, child: new Center(child: new Text("data"))),
        new Container(color: Colors.purple, child: new Center(child: new Text("data"))),
        new Container(color: Colors.yellow, child: new Center(child: new Text("data"))),
        new Container(color: Colors.green, child: new Center(child: new Text("data"))),
      ],
    );
  },
),

enter image description here

Upvotes: 7

Related Questions