0

I need to load data from BlocBuilder to a SliverGrid to show a grid of items.

When I use BlocBuilder as SliverGrid's delegate, I get this error:

The argument type 'BlocBuilder<dynamic, dynamic>' can't be assigned to the parameter type 'SliverChildDelegate'

What can I do?

This is a sample of my code:

      SliverGrid(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          crossAxisSpacing: 8,
          mainAxisSpacing: 8,
        ),
        delegate: BlocBuilder<SubjectBloc, SubjectState>(
          builder: (context, state) {
            return SliverChildBuilderDelegate(
              (
                BuildContext context,
                int index,
              ) {
                return Text('$index');
              },
            );
          },
        ),
      ),
Hossein Yousefpour
  • 3,827
  • 3
  • 23
  • 35
  • Ok. So, you need to pass `SliverChildBuilderDelegate` to the `delegate` property of `SliverGrid`. Now, you want the `BlockBuilder` to return a Widget instead. I will answer this below. – Preet Shah Feb 23 '21 at 08:56

2 Answers2

1

This is how I did it. If you know a better solution, please let me know.

        SliverList(
          delegate: SliverChildListDelegate(
            [
              BlocBuilder<SampleCubit, SampleState>(
                builder: (context, state) => (state is SampleLoaded)
                    ? GridView.builder(
                        shrinkWrap: true,
                        physics: const NeverScrollableScrollPhysics(),
                        itemCount: state.userList.length,
                        gridDelegate:
                            const SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 2,
                          crossAxisSpacing: 4,
                          mainAxisSpacing: 4,
                        ),
                        itemBuilder: (BuildContext context, int index) {
                          return Text('$index');
                        },
                      )
                    : Text(
                        'str_noItemFound'.tr,
                      ),
              )
            ],
          ),
        ),
Hossein Yousefpour
  • 3,827
  • 3
  • 23
  • 35
  • If it works, good for you, if not then use my 2nd solution. It should work. – Preet Shah Feb 23 '21 at 12:44
  • @PreetShah I have complex silvers inside the CustomScrollView! A SilverAppBar, A SilverList with items, And a SilverGrid It's not preferred to rebuild all this complex widget tree for a list of new data! – Hossein Yousefpour Feb 24 '21 at 10:36
  • Well, you have to make choice. See, your Widget depends on the data on the block. So, you will have to wait for the data in order to build stuff. With respect to performance, it is not desired. But it is what it is. – Preet Shah Feb 24 '21 at 10:47
0

Try this:

SliverGrid(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    crossAxisSpacing: 8,
    mainAxisSpacing: 8,
  ),
  delegate: SliverChildBuilderDelegate(
    (BuildContext context, int index) {
      return BlocBuilder<SubjectBloc, SubjectState>(
        builder: (context, state) {
          // Return Widgets from here.
          return Text('$index');
        },
      );
    },
  ),
),

Edit 1

Or this:

BlocBuilder<SubjectBloc, SubjectState>(
  builder: (context, state) {
    return SliverGrid(
      // Please specify the count according to the data
      // from the BlocBuilder.
      childCount: 20,
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        crossAxisSpacing: 8,
        mainAxisSpacing: 8,
      ),
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return Text('$index');
        },
      ),
    },
  );
),
Preet Shah
  • 792
  • 5
  • 12
  • The BlocBuilder returns a List, which I want to build the SilverGrid based on it! In your sample, I have no control over the SilverGrid itemCount. – Hossein Yousefpour Feb 23 '21 at 09:11
  • 1
    Can you describe what exactly do you need? Because the SliverGrid has many different purposes. Also, if you have an already determined ItemCount, then that would be better. Or, I will also give an alternate to the current answer. Maybe, that would help. – Preet Shah Feb 23 '21 at 09:15