Home > Software design >  Flutter: strange bug in row with aligment spaceEvenly
Flutter: strange bug in row with aligment spaceEvenly

Time:10-11

In my app, I often use conditional widget visibility to hide or display a widget. It works fine but recently, the design was not as expected as you can see in below images. enter image description here enter image description here

All Chips are laid in a Row with mainAxisAlignment: MainAxisAlignment.spaceEvenly. When there are 5 buttons, the design is ok, but with 4 buttons (the middle one is hidden), a additional space appears in the middle, which is not perfect.

Here the code

Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          ActionChip(
            backgroundColor: Theme.of(context).colorScheme.onSecondary,
            padding: EdgeInsets.all(4),
            shape: const CircleBorder(),
            label: const Icon(
              Icons.school,
            ),
            onPressed: () {...         
            },
          ),
          ActionChip(
            backgroundColor: Theme.of(context).colorScheme.onSecondary,
            padding: EdgeInsets.all(4),
            shape: const CircleBorder(),
            label: const ImageIcon(
              AssetImage("assets/images/Intervention.png"),
            ),
            onPressed: () {
              ...
            },
          ),
          deviceId != -1
              ? ActionChip(
                  backgroundColor:
                      Theme.of(context).colorScheme.onSecondary,
                  padding: EdgeInsets.all(4),
                  shape: const CircleBorder(),
                  label: const ImageIcon(
                    AssetImage("assets/images/History.png"),
                  ),
                  onPressed: () {
                    ...
                  },
                )
              : const SizedBox(
                ),
          ActionChip(
            backgroundColor: Theme.of(context).colorScheme.onSecondary,
            padding: EdgeInsets.all(4),
            shape: const CircleBorder(),
            label: const Icon(
              Icons.save_alt,
            ),
            onPressed: () {
              ...
            },
          ),
          ActionChip(
            backgroundColor: Theme.of(context).colorScheme.onSecondary,
            padding: EdgeInsets.all(4),
            shape: const CircleBorder(),
            label: const Icon(
              Icons.settings,
            ),
            onPressed: () {
             ...
            },
          ),
        ],
      ),

I tried to put the middle button in a Visibility widget, but the result was the same. How to solve this ugly problem? Thank you

CodePudding user response:

When you use SizedBox it actually take invisible space in that row so row consider it as an item and put padding around it because of spaceEvenly setting. Instead of put SizedBox in else condition, you can use if and set nothing for else condition, like this:

 Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          ActionChip(
            backgroundColor: Theme.of(context).colorScheme.onSecondary,
            padding: EdgeInsets.all(4),
            shape: const CircleBorder(),
            label: const Icon(
              Icons.school,
            ),
            onPressed: () {...         
            },
          ),
          ActionChip(
            backgroundColor: Theme.of(context).colorScheme.onSecondary,
            padding: EdgeInsets.all(4),
            shape: const CircleBorder(),
            label: const ImageIcon(
              AssetImage("assets/images/Intervention.png"),
            ),
            onPressed: () {
              ...
            },
          ),
          if(deviceId != -1) //<--- add this
              ActionChip(
                  backgroundColor:
                      Theme.of(context).colorScheme.onSecondary,
                  padding: EdgeInsets.all(4),
                  shape: const CircleBorder(),
                  label: const ImageIcon(
                    AssetImage("assets/images/History.png"),
                  ),
                  onPressed: () {
                    ...
                  },
                ),
          ActionChip(
            backgroundColor: Theme.of(context).colorScheme.onSecondary,
            padding: EdgeInsets.all(4),
            shape: const CircleBorder(),
            label: const Icon(
              Icons.save_alt,
            ),
            onPressed: () {
              ...
            },
          ),
          ActionChip(
            backgroundColor: Theme.of(context).colorScheme.onSecondary,
            padding: EdgeInsets.all(4),
            shape: const CircleBorder(),
            label: const Icon(
              Icons.settings,
            ),
            onPressed: () {
             ...
            },
          ),
        ],
      ),

Result: top row is for using if the second row is for not using it:

enter image description here

  • Related