Виджет видимости занимает область в виджете строки?

#flutter

#трепетать #всплывающее окно

Вопрос:

В моем коде третий контейнер не должен быть включен, поскольку он заключен в Visibility виджет. Это то, что я пробовал,

  Row(
     mainAxisAlignment: MainAxisAlignment.spaceAround,
     children: <Widget>[
         Container(...),
         Container(...),
         Visibility(visible:false, child: Container(...))
     ]
)
  

Как это должно выглядеть:

как это должно выглядеть

Что на самом деле произошло:

что произошло на самом деле

Комментарии:

1. Visibility Виджет устанавливает непрозрачность своего дочернего элемента в 0, когда для visible параметра установлено значение true. Итак, дочерний элемент все еще там, он просто не виден для глаз.

Ответ №1:

Согласно документации по видимости:

По умолчанию свойство visible определяет, включен ли дочерний элемент в поддерево или нет; когда он не виден, вместо него включается дочерний элемент замены (обычно поле нулевого размера).

Это показывает, что только потому, что виджет заключен в Visibility виджет, не означает, что он не существует в дереве виджетов.

Лучший способ добиться этого — сделать виджет null таким образом, чтобы он не включался в дерево виджетов.

 bool notNull(Object o) => o != null;
bool isVisible = false;
...

 Row(
     mainAxisAlignment: MainAxisAlignment.spaceAround,
     children: <Widget>[
         Container(...),
         Container(...),
         isVisible? Container(...) : null,
     ].where(notNull).toList(),
)
  

Или вы могли бы дополнительно создать список в методе сборки, чтобы вы могли просто добавить свой виджет в список, если выполняется определенное условие.

 Builder(
  build: (context) {
     bool isVisible = false;
     List<Widget> _children = [
       Container(...),
       Container(...),
     ];

     if (isVisible) {
        _children.add(Container(...)); // Optional widget
     }

     return Row(
       mainAxisAlignment: MainAxisAlignment.spaceAround,
       children: _children,
     );
  }
),
  

Комментарии:

1. Я думаю, что первый вариант подходит! Так просто и эффективно

2. @blackkara Я точно знаю! Это намного удобнее, чем добавление виджета Builder. Изначально из github.com/flutter/flutter/issues/3783

Ответ №2:

Действительно, ваш виджет не виден, но он учитывается при расчете интервала.

Вы можете попробовать использовать конструктор

 Builder(
  build: (context) {
     var children = [
       Container(...),
       Container(...),
     ];

     if (your condition) {
        childern.add(Container(...));
     }

     return Row(
       mainAxisAlignment: MainAxisAlignment.spaceAround,
       children: children
     );
  }
);