Пространство между дочерними элементами Column во Flutter

У меня есть виджет Column с двумя TextField виджетами в качестве дочерних, и я хочу, чтобы между ними было некоторое пространство.

Я уже пробовал mainAxisAlignment: MainAxisAlignment.spaceAround, но результат оказался не таким, как я хотел.


person Sachin Soma    schedule 12.10.2018    source источник
comment
Просто поместите SizedBox (высота: 15,0,) между двумя текстовыми полями   -  person anmol.majhail    schedule 12.10.2018


Ответы (15)


Вы можете использовать Padding виджет между этими двумя виджетами или обернуть эти виджеты Padding виджетами.

Обновить

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

Ex:

Column(
  children: <Widget>[
    Widget1(),
    SizedBox(height: 10),
    Widget2(),
  ],
),
person Viren V Varasadiya    schedule 12.10.2018
comment
Я очень хочу, чтобы это свойство было включено в column-class. Это будет пустой тратой времени на программирование, чтобы получить отступы между всеми дочерними элементами. - person Haroun Hajem; 28.04.2019
comment
Как можно обернуть два виджета в виджет Padding, если виджеты заполнения принимают только один дочерний параметр? - person Scorb; 11.09.2019
comment
@ScottF в ответе сказано, что виджет Padding находится между двумя виджетами. Дело не в том, что 2 виджета становятся дочерними для Padding. - person marcusljx; 01.12.2019
comment
Он прямо говорит или оборачивает эти виджеты с помощью виджета Padding .... - person Scorb; 01.12.2019
comment
@ScottF Сделайте дочерний элемент столбцом или строкой с двумя виджетами в качестве дочерних элементов. - person Riley Fitzpatrick; 30.12.2019

Вы можете поместить SizedBox с определенным height между виджетами, например:

Column(
  children: <Widget>[
    FirstWidget(),
    SizedBox(height: 100),
    SecondWidget(),
  ],
),

Почему это предпочтительнее, чем упаковка виджетов в Padding? Удобочитаемость! Менее визуальный шаблон, меньше отступов, а код соответствует типичному порядку чтения.

person Marcel    schedule 14.10.2018
comment
Добавление рамки размера похоже на добавление пустого представления, верно? не приведет ли это к каким-либо проблемам? - person user5381191; 29.09.2020
comment
SizedBox - это обычный виджет, который имеет желаемый размер, который он пытается быть во время макета, но ничего не отображает. Все листовые виджеты, такие как Text или Container, тоже пусты, так что ничего страшного. - person Marcel; 01.10.2020

вы можете использовать виджет Wrap() вместо Column(), чтобы добавить пространство между дочерними виджетами, и использовать свойство spacing, чтобы обеспечить равное расстояние между дочерними элементами

Wrap(
  spacing: 20, // to apply margin in the main axis of the wrap
  runSpacing: 20, // to apply margin in the cross axis of the wrap
  children: <Widget>[
     Text('child 1'),
     Text('child 2')
  ]
)
person Mahdi Tohidloo    schedule 12.05.2019
comment
Используйте runSpacing вместо spacing для промежутков между вертикально расположенными элементами - person Arpit; 14.06.2019
comment
Это сработало для меня. Я думаю, что это лучшее решение, но каковы будут недостатки использования Wrap () вместо Column ()? - person Lima Chaves; 01.09.2019
comment
Столбец - это расширенный виджет, а Wrap - нет. поэтому, когда вы хотите расширить все пространство родительского элемента, вы должны использовать расширенные виджеты, такие как столбец или строка и т. д. Это зависит от вашего случая - person Mahdi Tohidloo; 05.09.2019
comment
Да, это намного лучше, чем заворачивать каждого ребенка индивидуально. Хорошее предложение. - person kevinH; 06.09.2019
comment
что лучше для Flutter Web? - person SalahAdDin; 21.04.2021
comment
Это идеально, если вы хотите сблизить два виджета. Просто сделайте runSpacing отрицательным значением. - person Jaidyn Belbin; 30.06.2021

Просто используйте padding, чтобы обернуть его так:

Column(
  children: <Widget>[
  Padding(
    padding: EdgeInsets.all(8.0),
    child: Text('Hello World!'),
  ),
  Padding(
    padding: EdgeInsets.all(8.0),
    child: Text('Hello World2!'),
  )
]);

Вы также можете использовать Container (padding ...) или SizeBox (height: x.x). Последний из них является наиболее распространенным, но он будет зависеть от того, как вы хотите управлять пространством своих виджетов. Мне нравится использовать отступы, если пространство действительно является частью виджета, и использовать sizebox, например, для списков.

person dmarquina    schedule 12.10.2018
comment
есть ли способ сделать что-то вроде css grid-gap? - person Aseem; 02.11.2019

Есть много способов сделать это, я перечислю несколько здесь.

  1. Используйте Container и задайте высоту:

    Column(
      children: <Widget>[
        Widget1(),
        Container(height: 10), // set height
        Widget2(),
      ],
    )
    
  2. Используйте Spacer

    Column(
      children: <Widget>[
        Widget1(),
        Spacer(), // use Spacer
        Widget2(),
      ],
    )
    
  3. Используйте Expanded

    Column(
      children: <Widget>[
        Widget1(),
        Expanded(child: SizedBox()), // use Expanded
        Widget2(),
      ],
    )
    
  4. Используйте mainAxisAlignment

    Column(
      mainAxisAlignment: MainAxisAlignment.spaceAround, // mainAxisAlignment
      children: <Widget>[
        Widget1(),
        Widget2(),
      ],
    )
    
  5. Используйте Wrap

    Wrap(
      direction: Axis.vertical, // make sure to set this
      spacing: 20, // set your spacing
      children: <Widget>[
        Widget1(),
        Widget2(),
      ],
    )
    
person CopsOnRoad    schedule 12.10.2019
comment
Это СУПЕР полезно знать, как это сделать. Спасибо, что поделился! - person dustinrwh; 15.06.2021

Column(
  children: <Widget>[
    FirstWidget(),
    Spacer(),
    SecondWidget(),
  ]
)

Разделитель создает гибкое пространство для вставки в виджет [Гибкий]. (Как столбец)

person user9139407    schedule 31.07.2019
comment
Пожалуйста, добавьте пояснения к своему ответу, чтобы помочь другим лучше понять его. Ответы только на код считаются невежливыми, и это может не помочь OP понять проблему, с которой вы пытаетесь помочь. - person Michael; 01.08.2019

Я не вижу здесь этого решения, поэтому для полноты картины выложу его.

Вы также можете заключить детей в Padding, используя map:

Column(
      children: [Text('child 1'), Text('child 2')]
          .map(
            (e) => Padding(
              padding: const EdgeInsets.all(8),
              child: e,
            ),
          )
          .toList(),
    );
person mightybruno    schedule 18.03.2021
comment
Это лучший способ, чем добавлять sizedBox() после каждого виджета. - person abrsh; 10.04.2021

Таким же образом SizedBox используется выше для кода. удобочитаемость, вы можете использовать виджет Padding таким же образом и не делать его родительским виджетом для любого из дочерних элементов Column.

Column(
  children: <Widget>[
    FirstWidget(),
    Padding(padding: EdgeInsets.only(top: 40.0)),
    SecondWidget(),
  ]
)
person Al-Ameen    schedule 01.06.2019

Вы можете решить эту проблему по-другому.

Если вы используете Строка / Столбец, вам необходимо использовать mainAxisAlignment: MainAxisAlignment.spaceEvenly

Если вы используете виджет Wrap, вам необходимо использовать runSpacing: 5, spacing: 10,

В любом месте вы можете использовать SizeBox ()

person Md.Tarikul Islam    schedule 28.08.2019

Столбцы по умолчанию не имеют высоты, вы можете обернуть столбец в контейнер и добавить определенную высоту в свой контейнер. Затем вы можете использовать что-то вроде ниже:

Container(
   width: double.infinity,//Your desire Width
   height: height,//Your desire Height
   child: Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
         Text('One'),
         Text('Two')
      ],
   ),
),
person Ali Esfandiari    schedule 02.06.2020

Здесь есть много ответов, но я поставлю здесь самый важный, который должен использовать каждый.

1. Столбец

 Column(
          children: <Widget>[
            Text('Widget A'), //Can be any widget
            SizedBox(height: 20,), //height is space betweeen your top and bottom widget
            Text('Widget B'), //Can be any widget
          ],
        ),

2. Обернуть

     Wrap(
          direction: Axis.vertical, // We have to declare Axis.vertical, otherwise by default widget are drawn in horizontal order
            spacing: 20, // Add spacing one time which is same for all other widgets in the children list
            children: <Widget>[
              Text('Widget A'), // Can be any widget
              Text('Widget B'), // Can be any widget
            ]
        )
person Jitesh Mohite    schedule 21.05.2020

Возможно, вам придется использовать виджет SizedBox () между дочерними элементами столбца. Надеюсь, это будет полезно

person Issa    schedule 14.06.2020
comment
Если у вас есть новый вопрос, задайте его, нажав кнопку Задать вопрос. Включите ссылку на этот вопрос, если она помогает понять контекст. - Из отзыва - person Bruno; 16.06.2020
comment
Это не дает ответа на вопрос. Как только у вас будет достаточная репутация, вы сможете комментировать любой пост; вместо этого предоставит ответы которые не требуют пояснений от автора вопроса. - Из отзыва - person Ram Sharma; 16.06.2020

Вы также можете использовать вспомогательную функцию, чтобы добавить интервал после каждого дочернего элемента.

List<Widget> childrenWithSpacing({
  @required List<Widget> children,
  double spacing = 8,
}) {
  final space = Container(width: spacing, height: spacing);
  return children.expand((widget) => [widget, space]).toList();
}

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

Column(
  children: childrenWithSpacing(
    spacing: 14,
    children: [
      Text('This becomes a text with an adjacent spacing'),
      if (true == true) Text('Also, makes it easy to add conditional widgets'),
    ],
  ),
);

Я не уверен, что это неправильно или есть потеря производительности для запуска детей через вспомогательную функцию для той же цели?

person refik    schedule 04.12.2020

Размер коробки в этом случае не поможет, телефон в альбомной ориентации.

body: Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        Expanded(
           child: Container(
            margin: EdgeInsets.all(15.0),
            decoration: BoxDecoration(
              color: Color(0xFF1D1E33),
              borderRadius: BorderRadius.circular(10.0),
            ),
          ),
        ),
        Expanded(
           child: Container(
            margin: EdgeInsets.all(15.0),
            decoration: BoxDecoration(
              color: Color(0xFF1D1E33),
              borderRadius: BorderRadius.circular(10.0),
            ),
          ),
        ),
        Expanded(
           child: Container(
            margin: EdgeInsets.all(15.0),
            decoration: BoxDecoration(
              color: Color(0xFF1D1E33),
              borderRadius: BorderRadius.circular(10.0),
            ),
          ),
        ),
      ],
     )
person Mendax    schedule 10.07.2020

Вот еще один вариант, включающий цикл for. Это может дать немного больше гибкости и следует принципу DRY.

Column(
  children: <Widget>[
    for (var i = 0; i < widgets.length; i++)
      Column(
        children: [
          widgets[i], // The widget you want to create or place goes here.
          SizedBox(height: 10) // Any kind of padding or other widgets you want to put.
        ])
  ],
),
person Antis    schedule 13.07.2021