Контейнер Expanded позволяет своему вложенному виджету child заполнить доступное пространство (или его часть) других контейнеров - Row и Column.
Для создания виджета Expanded применяется следующий конструктор:
Expanded({Key key, int flex: 1, @required Widget child})
Параметр child
представляет вложенный виджет, а параметр flex
задает флекс-фактор - величину, в соответствии с
которой виджету Expanded будет отводиться определенное пространство контейнера.
Сначала рассмотрим проблему, с которой мы можем столкнуться. Допустим, в контейнере Row мы хотим вывести относительно длинный текст:
import 'package:flutter/material.dart'; void main() { runApp(Container( padding: EdgeInsets.all(30), color: Colors.teal, child:Row( textDirection: TextDirection.ltr, crossAxisAlignment: CrossAxisAlignment.start, verticalDirection: VerticalDirection.down, children: <Widget>[ Text('Чрез несколько дней после отъезда Анатоля, Пьер получил записку от князя Андрея, извещавшего ' 'его о своем приезде и просившего Пьера заехать к нему.', textDirection: TextDirection.ltr) ], ) ) ); }
Если мы запустим приложение, то мы увидим что-то типа следующего:
Поскольку ширина контейнера Row недостаточна, чтобы вместить строку текста, то мы увидим желто-черную полоску и сообщение о превышении размера на столько пикселей. Тем не менее все остальное пространство Row под сторой текста у нас пусто. И было бы неплохо, чтобы вместо этой полоски мы видели бы перенос текста ниже, чтобы он заполнял все пространство Row. Для этого воспользуемся виджетом Expanded:
import 'package:flutter/material.dart'; void main() { runApp(Container( padding: EdgeInsets.all(30), color: Colors.teal, child:Row( textDirection: TextDirection.ltr, crossAxisAlignment: CrossAxisAlignment.start, verticalDirection: VerticalDirection.down, children: <Widget>[ Expanded( child: Text('Чрез несколько дней после отъезда Анатоля, Пьер получил записку от князя Андрея, извещавшего ' 'его о своем приезде и просившего Пьера заехать к нему.', textDirection: TextDirection.ltr) ) ] ) ) ); }
Флекс-фактор указывает на часть пространства контейнера, которая буде отдаваться виджету Expanded. При вычислении данной части пространства флекс-фактор данного виджета Expanded делиться на сумму флекс-факторов всех элементов. Полученное значение умножается на общее доступное простанство контейнера.
Например, пусть у нас есть следующий контейнер Row:
import 'package:flutter/material.dart'; void main() { runApp(Container( padding: EdgeInsets.only(top:25), color: Colors.white, child:Row( textDirection: TextDirection.ltr, crossAxisAlignment: CrossAxisAlignment.start, verticalDirection: VerticalDirection.down, children: <Widget>[ Expanded( child: Container(color: Colors.teal), flex: 3, ), Expanded( child: Container(color: Colors.red), flex:1 ), Expanded( child: Container(color: Colors.indigoAccent), flex: 2, ) ] ) ) ); }
Таким образом, у нас три виджета Expanded, каждый из которых содержит виджет Container с определенной цветовой окраской. Первый виджет Expanded имеет флекс-фактор 3, второй - 1, третий - 2. Сумма всех флекс-факторов равна 3 + 1 + 2 = 6. Поэтому первый виджет Expanded получить 3/6 или 1/2 пространства Row, второй виджет Expanded - 1/6 пространства Row, а третий виджет Expanded - 2/6 или 1/3 пространства Row.
Если flex-factor явным образом не указан, то по умолчанию он равен 1.
То же самое касается и при расположении в контейнере Column, только пространство будет делиться пропорционально по вертикали:
import 'package:flutter/material.dart'; void main() { runApp(Container( padding: EdgeInsets.only(top:25), color: Colors.white, child:Column( children: <Widget>[ Expanded( child: Container(color: Colors.teal), flex:3 ), Expanded( child: Container(color: Colors.red), flex:1 ), Expanded( child: Container(color: Colors.indigoAccent), flex: 2, ) ] ) ) ); }