JonasLevin
JonasLevin

Reputation: 2110

`SliverGrid` throws Exception after all children are removed from list

I'm dynamically removing children from a SliverGrid.count but when all children are removed the SliverGrid throws the Exception SliverGeometry is not valid: The "scrollExtent" is negative.
I think this error happens because when the list of children is empty the Grid has no children to render anymore and can't render itself. When I also just place a Container (which isn't removable) at the top of my dynamic list of children the error doesn't happen but the rest of my children get pushed down becuase of the AxisSpacing.

Is there another way to fix this issue than just placing a static `Container at the top or bottom of the children?

This is the code from my SliverGrid and the layout is also shown in an image below:

SliverGrid.count(
  mainAxisSpacing: 10.0,
  crossAxisSpacing: 10.0,
  crossAxisCount: segmentedControlGroupValue,
  children: <Widget>[
    for (var i = 0;
        i < sessionState.patientQuestionnaires.length;
        i++)
      Material(
        color: Colors.white,
        borderRadius: BorderRadius.circular(6),
        elevation: 6,
        shadowColor: Colors.black38,
        child: InkWell(
          onTap: () => showModalBottomSheet(
            context: context,
            isScrollControlled: true,
            backgroundColor: Colors.transparent,
            builder: (context) => PQBottomSheet(
              i: i,
            ),
          ),
          child: Padding(
            padding: const EdgeInsets.all(6.0),
            child: Row(children: [
              Expanded(
                child: Wrap(
                  runAlignment: WrapAlignment.center,
                  alignment: WrapAlignment.spaceBetween,
                  crossAxisAlignment: WrapCrossAlignment.center,
                  children: [
                    Icon(
                      Icons.assignment,
                      color: Theme.of(context).primaryColor,
                      size: segmentedControlGroupValue == 1
                          ? 30
                          : segmentedControlGroupValue == 2
                              ? 28
                              : 24,
                    ),
                    Text(
                      sessionState.patientQuestionnaires[i]
                          .credentialSubject.documentName,
                      style:
                          Theme.of(context).textTheme.bodyText1,
                      overflow: TextOverflow.ellipsis,
                    ),
                    Text(
                      DateFormat.yMMMd().format(DateTime.parse(
                              sessionState
                                  .patientQuestionnaires[i]
                                  .issuanceDate)
                          .toLocal()),
                      style: Theme.of(context)
                          .textTheme
                          .bodyText2!
                          .copyWith(
                            color: Theme.of(context)
                                .colorScheme
                                .onBackground
                                .withOpacity(0.5),
                          ),
                      overflow: TextOverflow.ellipsis,
                    ),
                  ],
                ),
              ),
              IconButton(
                  padding: const EdgeInsets.all(0.0),
                  visualDensity: VisualDensity.compact,
                  onPressed: () => Platform.isAndroid
                      ? showCupertinoModalPopup(
                          useRootNavigator: false,
                          context: context,
                          builder: (context) =>
                              CupertinoActionSheet(
                            actions: [
                              CupertinoActionSheetAction(
                                onPressed: () {},
                                child: Text(L.of(context).share),
                              ),
                              CupertinoActionSheetAction(
                                onPressed: () {
                                  Navigator.of(context).pop();
                                  setState(() {
                                    context
                                        .read<SessionCubit>()
                                        .deletePQ(
                                            i, sessionState);
                                  });
                                },
                                child: Text(
                                  L.of(context).delete,
                                  style: TextStyle(
                                      color: Theme.of(context)
                                          .errorColor),
                                ),
                              ),
                            ],
                            cancelButton:
                                CupertinoActionSheetAction(
                              onPressed: () =>
                                  Navigator.of(context).pop(),
                              child: Text(
                                L.of(context).cancel,
                              ),
                            ),
                          ),
                        )
                      : bottomSheet(
                          context: context,
                          buttons: [
                            SizedBox(
                              width: double.infinity,
                              child: TextButton(
                                onPressed: () {},
                                child: Text(L.of(context).share,
                                    style: Theme.of(context)
                                        .textTheme
                                        .bodyText1),
                              ),
                            ),
                            SizedBox(
                              width: double.infinity,
                              child: TextButton(
                                onPressed: () {
                                  Navigator.of(context).pop();
                                  setState(() {
                                    context
                                        .read<SessionCubit>()
                                        .deletePQ(
                                            i, sessionState);
                                  });
                                },
                                child: Text(
                                  L.of(context).delete,
                                  style: Theme.of(context)
                                      .textTheme
                                      .bodyText1!
                                      .copyWith(
                                        color: Theme.of(context)
                                            .errorColor,
                                      ),
                                ),
                              ),
                            ),
                          ],
                        ),
                  icon: const Icon(Icons.more_vert))
            ]),
          ),
        ),
      ),
  ],
),

enter image description here

Upvotes: 0

Views: 90

Answers (1)

immadisairaj
immadisairaj

Reputation: 656

Removing the complete SilverGrid widget when there are no items present might work. Because there has to be at least one widget inside the Grid.

if (sessionState.patientQuestionnaires.length > 0)
  SilverGrid.count(...),

Adding the above code will make the SilverGrid disappear and again appear when you add some content to the patientQuestionnaires.

Note: You need to setState() or an alternative to refresh the state when the item is removed/added. (Hopefully, you are already using one)

Upvotes: 1

Related Questions