skip to Main Content

I have a Flutter application where I’m using a Grid Builder to display a grid of items. After every 10 grids, I want to insert a fully stretched yellow container to separate the sections. For example, the first row should contain grids 1 to 5, the second row should contain grids 6 to 10, and then a yellow container should be inserted before displaying grids 11 to 15 on the next row. This pattern should continue until the end of the grid (e.g., 100 grids).

I have attached the current code and an image for reference. Could you please guide me on how to achieve this functionality? Thank you in advance.

GridView.builder(
        itemCount: 100,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 5,
        ),
        itemBuilder: (BuildContext context, int index) {
          if ((index + 1) % 11 == 0) {
            // Add yellow color stretch container after every 10th container
            return Container(
              color: Colors.yellow,
              height: 50,
              width: double.infinity,
            );
          } else {
            // Regular square rounded shape container
            return Container(
              margin: const EdgeInsets.all(8),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                color: Colors.white,
              ),
              child: Center(
                child: Text('${index + 1}'),
              ),
            );
          }
        },
      )

enter image description here

2

Answers


  1. Here’s a simple example.

    class TestScreen extends StatelessWidget {
      const TestScreen({super.key});
    
      @override
      Widget build(BuildContext context) {
        // The number you want to sperate the data.
        const int splitCount = 10;
    
        // Items that you have. Change this to suit your conditions.
        final List<int> items = List.generate(
          100,
          (index) => index,
        );
    
        return Scaffold(
          appBar: AppBar(
            centerTitle: true,
            title: const Text('Staggered GridView'),
          ),
          body: SafeArea(
            child: SingleChildScrollView(
              child: TestStaggerdGridView(
                items: items,
                splitCount: splitCount,
                crossAxisCount: 5,
              ),
            ),
          ),
        );
      }
    }
    
    class TestStaggerdGridView extends StatelessWidget {
      const TestStaggerdGridView({
        super.key,
        required this.items,
        required this.splitCount,
        required this.crossAxisCount,
      });
    
      /// Items that you have. Change this to suit your conditions.
      final List<int> items;
    
      /// The number you want to seprate the items.
      final int splitCount;
    
      /// The number of cell count in an axis.
      final int crossAxisCount;
    
      @override
      Widget build(BuildContext context) {
        final int addedCount = items.length ~/ (splitCount + 1);
    
        return StaggeredGrid.count(
          axisDirection: AxisDirection.down,
          crossAxisCount: crossAxisCount,
          children: List.generate(
            items.length + addedCount,
            (index) {
              if ((index + 1) % (splitCount + 1) == 0) {
                return StaggeredGridTile.count(
                  mainAxisCellCount: 1,
                  crossAxisCellCount: crossAxisCount,
                  child: _stretchedItem(),
                );
              } else {
                int itemIndex = (index - (index ~/ (splitCount + 1)));
    
                return StaggeredGridTile.count(
                  mainAxisCellCount: 1,
                  crossAxisCellCount: 1,
                  child: _normalItem(itemIndex),
                );
              }
            },
          ),
        );
      }
    
      Widget _normalItem(int itemIndex) {
        return Container(
          margin: const EdgeInsets.all(8),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(10),
            color: Colors.white,
          ),
          child: Center(child: Text('${itemIndex + 1}')),
        );
      }
    
      Widget _stretchedItem() {
        return Container(
          margin: const EdgeInsets.all(8),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(10),
            color: Colors.yellow,
          ),
        );
      }
    }
    

    enter image description here

    Login or Signup to reply.
  2. Here’s my take on it… using .skip and .take for the subgroups:

    final items = Iterable<int>.generate(47).toList();
    
    class Body extends StatelessWidget {
      const Body({
        super.key,
      });
    
      @override
      Widget build(BuildContext context) => ListView.separated(
            itemBuilder: (context, index) {
              final group = items.skip(index * 10).take(10).toList();
              if (group.isEmpty) return null;
              return GridView.count(
                crossAxisCount: 5,
                shrinkWrap: true,
                children: [
                  for (final item in group)
                    Container(
                      margin: const EdgeInsets.all(8),
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(10),
                        color: Colors.blue,
                      ),
                      child: Center(
                        child: Text('$item'),
                      ),
                    )
                ],
              );
            },
            separatorBuilder: (context, index) => const Divider(
              thickness: 32,
              height: 40,
              color: Colors.yellow,
            ),
            itemCount: (items.length / 10).ceil(),
          );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search