user7795119
user7795119

Reputation:

How do I center a GridView.builder within a column?

I am trying to center a GridView in the center of the phone screen.

I have already tried to use crossAxisAlignment and mainAxisAlignment, but to no avail. Below is my current code.

class CommanderDamage extends StatefulWidget {
  int damage = 0;
  CommanderDamage({this.damage, Key key});

  @override
  State<StatefulWidget> createState() {
    return CommanderDamageState();
  }
}

class CommanderDamageState extends State<CommanderDamage> {
  var damage = [0, 0, 0, 0, 0, 0];
  @override
  Widget build(context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(
              child: Container(
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [Color(0xfff6921e), Color(0xffee4036)],
                  ),
                ),
                child: GridView.builder(                 
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 2),
                  itemCount: damage.length,
                  itemBuilder: (BuildContext context, index) {
                    return Column(
                      children: <Widget>[
                        Expanded(
                          child: InkWell(
                            onTap: () {
                              setState(() {
                                damage[index]++;
                              });
                            },
                            onLongPress: () {
                              setState(() {
                                damage[index] = 0;
                              });
                            },
                            child: Column(
                              children: <Widget>[
                                Padding(
                                  padding: const EdgeInsets.all(15),
                                  child: Text(
                                    'Player ${index + 1}',
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontSize: 20.0,
                                        fontWeight: FontWeight.bold),
                                  ),
                                ),
                                Text(
                                  damage[index].toString(),
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 35.0,
                                      fontWeight: FontWeight.bold),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ],
                    );
                  },
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Currently, the Grid starts at the top of the screen, I would like it to be right in the center. Here is a mockup of what it looks like vs what I expect.

Upvotes: 5

Views: 11433

Answers (1)

Hugo Passos
Hugo Passos

Reputation: 8427

  1. Align your Container to the center.
  2. As kekub said, remove Expanded, as it will fill any remaining space on the main axis.
  3. As nonybrighto said, add shrinkWrap: true to your GridView, so it won't fill all vertical space.
  4. Align the main axis of your last Column to the center.

You'll end up with something like this:

@override
Widget build(context) {
  return MaterialApp(
    home: Scaffold(
      body: Container(
        alignment: Alignment.center,
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            colors: [Color(0xfff6921e), Color(0xffee4036)],
          ),
        ),
        child: GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          itemCount: damage.length,
          shrinkWrap: true,
          itemBuilder: (BuildContext context, index) {
            return InkWell(
              onTap: () {
                setState(() {
                  damage[index]++;
                });
              },
              onLongPress: () {
                setState(() {
                  damage[index] = 0;
                });
              },
              child: Container(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(15),
                      child: Text(
                        'Player ${index + 1}',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 20.0,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                    Text(
                      damage[index].toString(),
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 35.0,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    ),
  );
}

However, when you shrinkWrap, the Android's overscroll effect is going to get weird, since your GridView no longer uses the whole vertical space. I recommend changing GridView's physics to BouncingScrollPhysics.

Upvotes: 5

Related Questions