flutterflutter-gridview

Flutter StaggeredGridView not available on latest version of flutter_staggered_grid_view


What I'm trying to do is have a GridView with a variable/dynamic CrossAxisCount. I have a FutureBuilder retrieving data from an API and sometimes I need to show one item per line and sometimes I need to show two items per line, depending on some item properties. Being more specific the condition is: if (previousItem != null && items[index].idCategory != previousItem.idCategory && items[index].isOdd). The list of items would have around 700 items, please remember that crossAxisCount is final in most of the constructors. I found the following code on Stackoverflow but it is not compatible with the latest version of flutter_staggered_grid_view. I have other things on the app using version 0.6.2 of that package so I cannot use version ^0.4.0.

class Staggered extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     body: SafeArea(
       child: StaggeredGridView.count(
         crossAxisCount: 2,
         mainAxisSpacing: 5,
         crossAxisSpacing: 5,
         children: List.generate(14, (index){
           return Container(
             child: Center(
               child: Text("${index+1}"),
             ),
             color: Colors.blue,
           );
         }),
         staggeredTiles: buildTiles(),
       ),
     ),
   );
 }

 List<StaggeredTile> buildTiles(){
   return List.generate(14, (index){
     if((index+1)%7 == 0){
       return StaggeredTile.count(2, 1);
     }else{
       return StaggeredTile.count(1, 1);
     }
   });
 }
}

update: the following is exactly what I'm trying to achieve using the latest version of that package.

return StaggeredGridView.countBuilder(
                  crossAxisCount: 2,
                  mainAxisSpacing: 4,
                  crossAxisSpacing: 4,
                  itemCount: cards.length,
                  itemBuilder: (context, index) {
                    return Container(
                      width: 187,
                      height: 210,
                      color: Colors.red,
                      child: Text('$index - ${cards[index].id} - ${cards[index].idStoreCategory}',
                          style: const TextStyle(color: Colors.white, fontSize: 20)),
                    );
                  },
                  staggeredTileBuilder: (index) {
                    final nextItem = index < cards.length - 1 ? cards[index + 1] : null;
                    if (nextItem != null && cards[index].idStoreCategory != nextItem.idStoreCategory && index.isEven) {
                      return StaggeredTile.count(2, 1);
                    } else {
                      return StaggeredTile.count(1, 1);
                    }
                  },
                );```

Solution

  • So, you want a custom GridView widget which shows crossAxisCount dynamically based on your API response. Sometimes, single or N items in a row. So, here I wrote a sample code for you. I hope it helps you. Feel free to ask.

    import "package:flutter/material.dart";
    import "package:get/get.dart";
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
    
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(
          home: const Sample(),
          theme: ThemeData(),
        );
      }
    }
    
    class Sample extends StatefulWidget {
      const Sample({super.key});
    
      @override
      State<Sample> createState() => _SampleState();
    }
    
    class _SampleState extends State<Sample> {
      int currentIndex = 0;
    
      final List<List<dynamic>> items = <List<dynamic>>[
        <dynamic>["Hello"],
        <dynamic>["Hello", "World"],
        <dynamic>["Hello", "World", "Yay!"],
        <dynamic>["Hello"],
        <dynamic>["Hello", "World"],
        <dynamic>["Hello", "World", "Yay!"],
      ];
    
      @override
      Widget build(BuildContext context) {
        if (currentIndex != 0) {
          currentIndex = 0;
        } else {}
    
        return Scaffold(
          body: SafeArea(
            child: GridView.builder(
              shrinkWrap: true,
              itemCount: items.length,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: items[currentIndex].length,
                childAspectRatio: 16 / 9,
              ),
              itemBuilder: (BuildContext context, int builderIndex) {
                currentIndex = builderIndex;
                return Row(
                  children: List<Widget>.generate(
                    items[currentIndex].length,
                    (int listItemIndex) {
                      return SizedBox(
                        width: Get.width / items[currentIndex].length,
                        child: Text(items[currentIndex][listItemIndex]),
                      );
                    },
                  ),
                );
              },
            ),
          ),
        );
      }
    }
    
    

    Preview: Preview