← Назад к вопросам
В чём разница между Expanded и Flexible виджетами?
1.0 Junior🔥 192 комментариев
#Flutter виджеты
Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Expanded vs Flexible в Flutter
Оба виджета используются внутри Row/Column для управления распределением пространства, но работают по-разному.
Что их объединяет?
Оба виджета:
- Оборачивают дочерние элементы
- Работают только в Flex контейнерах (Row, Column)
- Имеют параметр
flex(по умолчанию 1) - Занимают доступное пространство
Flexible — гибкий, но не обязательный
Flexible позволяет виджету занять доступное пространство, но без обязательности. Если пространства нет — виджет сжимается до своего минимального размера.
Row(
children: [
Container(width: 100, color: Colors.blue, height: 50),
Flexible(
flex: 1,
fit: FlexFit.loose, // может быть меньше доступного пространства
child: Container(color: Colors.red, height: 50),
),
Container(width: 100, color: Colors.green, height: 50),
],
)
Параметр fit:
- FlexFit.loose (по умолчанию) — виджет может быть меньше доступного пространства
- FlexFit.tight — виджет обязательно займёт всё доступное пространство
Expanded — всегда займёт пространство
Expanded — это Flexible с fit: FlexFit.tight. Виджет обязательно займёт все доступное пространство, не может быть меньше.
Row(
children: [
Container(width: 100, color: Colors.blue, height: 50),
Expanded(
flex: 1,
child: Container(color: Colors.red, height: 50), // займёт всё свободное место
),
Container(width: 100, color: Colors.green, height: 50),
],
)
Это эквивалентно:
Flexible(
flex: 1,
fit: FlexFit.tight,
child: Container(color: Colors.red, height: 50),
)
Практическая разница
Сценарий 1: Кнопка внутри Row
Row(
children: [
Flexible(
child: ElevatedButton(
onPressed: () {},
child: Text(Кнопка),
),
),
],
)
// Результат: кнопка займёт только нужный размер, даже если пространства много
Сценарий 2: Растягивающееся поле ввода
Row(
children: [
Text(Поиск:),
Expanded(
child: TextField(
// займёт ВСЁ оставшееся место
),
),
],
)
Параметр flex — распределение пространства
Если несколько Flexible/Expanded виджетов с разными flex:
Row(
children: [
Expanded(
flex: 2,
child: Container(color: Colors.red),
),
Expanded(
flex: 1,
child: Container(color: Colors.blue),
),
],
)
// Red займёт 2/3 пространства, Blue — 1/3
Сравнительная таблица
| Параметр | Flexible | Expanded |
|---|---|---|
| Обязательно займёт место | Нет (loose по умолчанию) | Да |
| Может быть меньше доступного | Да | Нет |
| Fit по умолчанию | FlexFit.loose | FlexFit.tight |
| Управление flex | Да | Да |
| Использование | Гибкие элементы (кнопки, тексты) | Растягивающиеся элементы (поля ввода) |
Правило большого пальца
- Expanded — когда нужно обязательно заполнить пространство (TextField, контент)
- Flexible — когда элемент может быть меньше, но может вырасти если место есть (кнопки, иконки)
Пример: Форма логина
Column(
children: [
// Заголовок — не растягивается
Text(Вход),
SizedBox(height: 20),
// Поле Email — ОБЯЗАТЕЛЬНО растянуть
Expanded(
child: TextField(decoration: InputDecoration(label: Text(Email))),
),
SizedBox(height: 10),
// Поле пароля — ОБЯЗАТЕЛЬНО растянуть
Expanded(
child: TextField(decoration: InputDecoration(label: Text(Пароль))),
),
SizedBox(height: 20),
// Кнопка — займёт свой размер, может быть меньше
Flexible(
child: ElevatedButton(child: Text(Войти)),
),
],
)
Вывод: Expanded = Flexible + FlexFit.tight. Используй Expanded для обязательного заполнения пространства, Flexible для гибких элементов.