flutter - правильный способ создания поля, которое начинается с minHeight, увеличивается до maxHeight

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

Правильный виджет для этого, кажется, ConstrainedBox, вот так:

new ConstrainedBox(
  constraints: new BoxConstraints(
    minHeight: 35.0,
    maxHeight: 60.0,
  ),
  child: ...child with growing content (has default height 25.0)...
),

однако, это начинает коробку с maxHeight.

Я пытался использовать hasBoundedHeight, но не могу создать правильный синтаксис для него или найти пример в документации.

Каков наилучший способ заставить коробку работать, как описано?

9 ответов

Решение

Нет понятия "Начинается с максимального / минимального размера".

Дело в том, ContrainedBox только добавить ограничения для своего ребенка. Но в конце концов, он не выбирает размер.

Если вы хотите, чтобы ваш ребенок набрал minSize, он не должен тратить. Которые переводят в отсутствие ширины / высоты double.INFINITY, Факт в том, что double.INFINITY является значением по умолчанию для многих виджетов, в том числе Container,

С другой стороны, некоторые виджеты, такие как DecoratedBox по умолчанию имеет размер 0. Это означает, что этот код:

return new ConstrainedBox(
  constraints: new BoxConstraints(
    minHeight: 5.0,
    minWidth: 5.0,
    maxHeight: 30.0,
    maxWidth: 30.0,
  ),
  child: new DecoratedBox(
    decoration: new BoxDecoration(color: Colors.red),
  ),
);

Будет отображать 5.0*5.0 красный квадрат.

Пример ниже поможет вам увеличить размер виджета по мере необходимости.

Container(
          color: Colors.blueAccent,
          constraints: BoxConstraints(
              minHeight: 100, minWidth: double.infinity, maxHeight: 400),
          child: ListView(
            shrinkWrap: true,
            children: <Widget>[
              ...List.generate(
                10,  // Replace this with 1, 2 to see min height works. 
                (index) => Text(
                  'Sample Test: ${index}',
                  style: TextStyle(fontSize: 60, color: Colors.black),
                ),
              ),
            ],
          ),
        ),

Выход для минимальной высоты для одного предмета:

Выход для минимальной высоты для 10 элементов:

Примечание. При этом будут отображаться виджеты в соответствии с указанной максимальной высотой.

Позволь мне объяснить:

Если дочерним элементом является ( виджет) или (ListViewвиджет),maxHeightне будет работать так, как ожидалось, оно будет работать какheight, чтобы решить это:

1 - Если дочерний элемент is , ваш код должен быть таким:

       Container(
    constraints: BoxConstraints(
      maxHeight: MediaQuery.of(context).size.height * .30
    ),
    child: SingleChildScrollView(
      child: Column(
        mainAxisSize: MainAxisSize.min,
  
        children: const [
          // growable childrens
        ],
      ),
    ),
);

2- Если ребенокColumn, ваш код должен быть таким:

      Container(
  constraints: BoxConstraints(
    maxHeight: MediaQuery.of(context).size.height * .20,
  ),
  child: ListView(
    scrollDirection: Axis.vertical,
    shrinkWrap: true,
    children: const [
      // growable childrens
    ],
  ),
);

Как и в случае, если ребенокBoxConstraintsявляетсяRow,maxWidthне будет работать так, как ожидалось, оно будет работать какwidth, чтобы решить, что вам нужно установитьmainAxisSizeкMainAxisSize.minтак:

       Container(
    constraints: BoxConstraints(
      maxWidth: MediaQuery.of(context).size.width * .15
    ),
    child: SingleChildScrollView(
      child: Row(
        mainAxisSize: MainAxisSize.min,
  
        children: const [
          // growable childrens
        ],
      ),
    ),
);

Например, minHeightне работает. Я решил это, используя этот хак:

      ConstrainedBox(
  constraints: BoxConstraints(minHeight: 150),
  child: Stack(
    children: [
      Column(
        children: [dynamicChild1, dynamicChild2],
      ),
    ],
  ),
);

Итак, просто обернув Columnв Stack. Теперь размер столбца стал 150 и более.

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

double deviceWidth = MediaQuery.of(context).size.width;
double deviceHeight = MediaQuery.of(context).size.height;

В width а также height свойство Container использовать deviceWidth а также deviceHeight чтобы сформировать ваше состояние.

Container(
width: deviceWidth<200?50:deviceWidth*0.5,
height: deviceHeight<500?50:deviceHeight>800?200:deviceHeight*0.2,
child: //child,
)

Примечание: только тернарный оператор ?: работает для указания условия для высоты и ширины

Да, ConstrainedBox - правильный виджет для этой цели. Если вы укажете только параметр minHeight, например. 300, ребенок будет иметь минимальный рост и будет увеличивать свой размер в соответствии с содержимым.

Вот пример:

ConstrainedBox(
   constraints: BoxConstraints(
       minHeight: 300,
       ),
   child: Container(child : SomeWidget(),)

Если высота, требуемая SomeWidget(), меньше 300, она будет иметь высоту 300. В противном случае она соответственно увеличит ее высоту. Для украшения и структурирования SomeWidget() вы можете использовать отступы и другие свойства контейнера.

       ConstrainedBox(
   constraints: BoxConstraints(
      minWidth: 70, 
      minHeight: 70,
      maxWidth: 150, 
      maxHeight: 150,
   ),
   child: Container(color: Colors.red, width: 10, height: 10),
)

Вы могли догадаться, что Containerдолжно быть от 70 до 150 пикселей, но вы ошибаетесь. В ConstrainedBoxтолько накладывает дополнительные ограничения на те, которые он получает от своего родителя.

Здесь экран заставляет ConstrainedBox быть точно такого же размера, как экран, поэтому он сообщает своему дочернему элементу Container также принять размер экрана, игнорируя его constraints параметр.

Как указывает ответ Реми, если вы изначально максимизируете размер, когда вы ожидали, что он будет ближе к минимуму или на минимуме, это потому, что ребенок хочет быть большим. (Re: Ограничения уменьшаются. Размеры увеличиваются. Родитель устанавливает позицию. ) Если вы не уверены, какой дочерний элемент вызывает это, один из удобных способов — использовать инспектор виджетов в вашей среде IDE и проверить свойства потомков, а затем проверить документы о том, почему и настроить соответственно.

Например, я столкнулся с этим, например, при заключении виджета в . Обычно без ограничений центрированный виджет будет соответствовать высоте дочернего элемента. Однако при размещении внутри a внезапно он взорвался до максимальных ограничений. Проверив документы, я увидел, что:

  1. , объясняя новый макет.
  2. Но: , что объясняет поведение без .
  3. И это говорит мне, как это исправить: , т.е. установить х .

Так что обратите внимание на то, как ведут себя ваши дети! Если вы накладываете внешние ограничения, они могут быть жадными (или нет, как настоящие дети ;).

попробуйте использовать поле Contraints вместо поля Sized, потому что размерное поле не имеет свойств минимальной высоты и минимальной ширины, они просто имеют свойство высоты и ширины

       ConstrainedBox(
      constraints: const BoxConstraints(
        maxHeight: Dimension.d9,
        minHeight: Dimension.d9,
        maxWidth: 144.0
      ),
    );
Другие вопросы по тегам