TransWikia.com

Making a 2x2 grid in Flutter

Stack Overflow Asked by Zerok on December 16, 2021

I’m trying to create a 2×2 grid for displaying some info in cards. Disclaimer: I’m totally new to Dart and Flutter, so expect a lot of ignorance on the topic here.

These cards should have a fixed size, have an image, display some text… and be positioned from left to right, from top to bottom.

First, I tried to use the Flex widget, but it seems to only work horizontally or vertically. Therefore, my only solution was to use two Flexes, but only showing the second when the amount of elements is higher than 2 (which would only use one row).

Then, I tried using GridView, but it doesn’t work in any possible way. It doesn’t matter which example from the Internet I copy and paste to begin testing: they just won’t show up in the screen unless they’re the only thing that is shown in the app, with no other widget whatsoever. I still don’t understand why that happens.

This is my current code:

First widgets in "home_page.dart":

return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            Padding(padding: EdgeInsets.only(top: 30)),
            Text(
              'App test',
              style: TextStyle(fontSize: 24),
            ),
            EventsList(key: new Key('test')),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );

The "EventList" part is a widget that should represent the grid functionality I explained before. This class gets some info from a service (which currently just sends some hardcoded info from a Future), and paints the given widgets ("Card" items, basically) into the EventList view:

class _EventsListState extends State<EventsList> {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Event>>(
        future: new EventsService().getEventsForCoords(),
        builder: (context, AsyncSnapshot<List<Event>> snapshot) {
          if (snapshot.hasData) {
            return Padding(
                padding: EdgeInsets.only(left: 20, right: 20),
                child: Flex(
                  direction: Axis.horizontal,
                  verticalDirection: VerticalDirection.down,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: generateProximityEventCards(snapshot.data),
                ));
          } else {
            return CircularProgressIndicator();
          }
        });
  }

  List<Card> generateProximityEventCards(List<Event> eventList) {
    // Load Events from API
    print(eventList);

    // Render each card
    return eventList.map((Event ev) {
      return Card(
          child: Padding(
        padding: EdgeInsets.only(bottom: 15),
        child: Column(
          children: <Widget>[
            Image(
              fit: BoxFit.cover,
              image: ev.imageUrl,
              height: 100,
              width: 150,
            ),
            Padding(
              child: Text(ev.name),
              padding: EdgeInsets.only(left: 10, right: 10),
            ),
            Padding(
              child: Text(ev.address),
              padding: EdgeInsets.only(left: 10, right: 10),
            ),
          ],
        ),
      ));
    }).toList();
  }
}

This is how it currently looks:

As I said before, I understand that the Flex widget can’t really get that 2×2 grid look that I’m looking for, which would be something like this (done with Paint):

So, some questions:

  1. How can I get a grid like that working? Have in mind that I want to have more stuff below that, so it cannot be an "infinite" grid, nor a full window grid.
  2. Is it possible to perform some scrolling to the right in the container of that grid? So in case there are more than 4 elements, I can get to the other ones just scrolling with the finger to the right.
  3. As you can see in the first image, the second example is bigger than the first. How to limit the Card’s size?

Thank you a lot for your help!

2 Answers

The reason the gridview was not working is because you need to set the shrinkWrap property of theGridView to true, to make it take up as little space as possible. (by default, scrollable widgets like gridview and listview take up as much vertical space as possible, which gives you an error if you put that inside a column widget)

Try using the scrollable GridView.count widget like this and setting shrinkWrap to true:

...

GridView.count(
  primary: false,
  padding: /* You can add padding: */ You can add padding const EdgeInsets.all(20),
  crossAxisCount: /* This makes it 2x2: */ 2,
  shrinkWrap: true,
  children: generateProximityEventCards(snapshot.data),

...

Answered by Nate Giraudeau on December 16, 2021

Is this what you exactly want?

do let me know so that I can update the code for you

import 'package:flutter/material.dart';

class List extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        title: Text('Inicio', style: TextStyle(color: Colors.black, fontSize: 18.0),),
      ),

      body: GridView.count(
        shrinkWrap: true,
        crossAxisCount: 2,
        children: List.generate(
          50,//this is the total number of cards
          (index){
            return Container(
              child: Card(
                color: Colors.blue,
              ),
            );
          }
        ),
      ),
    );
  }
}

Answered by littleironical on December 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP