Skip an item in gridview without leaving a hole

Viewed 348

I'm building a gridview displaying thumbnails and do not want to show the items at index 0. I have a different widget where I show thumbnails using a listview with the Visibility widget. That works!

Like so:

ListView.separated(
                separatorBuilder: (BuildContext context, int index) =>
                    SizedBox(
                      width: mainElementSize * 0.02,
                    ),
                scrollDirection: Axis.horizontal,
                controller: paneController,
                physics: const BouncingScrollPhysics(
                    parent: AlwaysScrollableScrollPhysics()),
                addAutomaticKeepAlives: true,
                reverse: true,
                itemCount: mainElementList.mainElementList.length,
                //
                itemBuilder: (BuildContext context, int index) {
                  return Visibility(
                    visible: index > 0,
                    child: UnconstrainedBox(
                      child: HistoryThumb(
                        index: index,
                      ),
                    ),
                  );
                }),

The gridview does work with Visibility, but different. Instead of just skipping the object, it leaves a whole in the grid. Code:

GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 4,
          mainAxisSpacing: gridheight * 0.015,
          crossAxisSpacing: gridWidth * 0.015,
        ),
        padding: EdgeInsets.symmetric(
          horizontal: 0,
        ),
        physics: const BouncingScrollPhysics(
            parent: AlwaysScrollableScrollPhysics()),
        itemCount:
            Provider.of<MainElementList>(context).mainElementList.length,
        //
        itemBuilder: (context, index) => Visibility(
              visible: index > 0,
              child: UnconstrainedBox(
                child: HistoryThumb(
                  index: index,
                ),
              ),
            )),

Screenshot:

enter image description here

Any way to not have it do that? I found a similar topic here: How to skip build in item builder gridview.builder Flutter Firebase Stream Builder

But I do not want to build a seperate list and duplicate all my objects just to display the thumbnails. Isn't there something more elegant for skipping certain items?

2 Answers

Instead of using Visibility widget you can apply ternary operator and pass SizedBox at index 0:-

index == 0 ? SizedBox() : UnconstrainedBox(
            child: HistoryThumb(
              index: index,
            ),
          ),

Can you try like this:-

GridView.builder(
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 4,
      mainAxisSpacing: gridheight * 0.015,
      crossAxisSpacing: gridWidth * 0.015,
    ),
    padding: EdgeInsets.symmetric(
      horizontal: 0,
    ),
    physics: const BouncingScrollPhysics(
        parent: AlwaysScrollableScrollPhysics()),
    itemCount:
        Provider.of<MainElementList>(context).mainElementList.length - 1,
    //
    itemBuilder: (context, index) => Visibility(
          visible: index > 0,
          child: UnconstrainedBox(
            child: HistoryThumb(
              index: index+1,
            ),
          ),
        )),

subtract 1 from itemCount and add 1 in Index history Thumb. I think we can't skip an certain item in the build but we can achieve what you want from this!!

You can achieve your required behaviour by moving your particular item to the end of the list; then you can simply hide that last item in the grid view.

This way, you wont see any whitespace in middle of the grid view.

For example:

List<String> list = [
"mustafa",
"hawari",
"ravi",
"shyam"
];
  int indexOfItem = list.indexOf("hawari");
  String itemTobeAddedAtLast = list[indexOfItem];
  list.removeAt(indexOfItem);
  list.insert(list.length, itemTobeAddedAtLast);

  print(list); 
  // this returns 
  // [mustafa, ravi, shyam, hawari]
Related