Flexible — Flutter изпълним елемент, който управлява как дъщерният елемент заема наличното пространство във Flex-контейнер. За разлика от Expanded, Flexible не принуждава детето да запълни цялата определена област — дъщерният изпълним елемент може да бъде по-малък, а останалото пространство остава празно. Според официалната документация на Flutter (2026), Flexible е необходим в сценарии, където се изисква гъвкаво разпределение на пространството без принудително разтягане: бутони с минимална ширина, текстови блокове с естествен размер и елементи с intrinsic constraints.
Основни точки
Flexible — обвиващ елемент, който предоставя на дъщерния елемент гъвкаво пространство във Flex-контейнер. Flexible, подобно на Expanded, участва в разпределението на свободното пространство, но с ключова разлика: детето на Flexible може да заеме по-малко място от определеното, ако собственият му размер е по-малък от наличното пространство.
Flexible използва Flex-алгоритъма на Flutter за изчисляване на наличното пространство. Първо рамката запитва всички негъвкави деца (елементи без Flexible/Expanded) и изчислява техния intrinsic size. Останалото пространство се разделя между гъвкавите деца пропорционално на техния flex-фактор. След разпределяне на пространството, Flexible проверява fit — ако е loose, към дъщерния елемент се прилага ограничение “не повече от определеното”, позволявайки му да остане малък.
Характеристика на Flexible: ако дъщерният елемент има свои минимални размери (например Text с дълъг низ), Flexible разпределя поисканото пространство, без да го разтяга принудително. Това прави Flexible незаменим за елементи, чийто размер трябва да се определя от съдържанието, а не от контейнера.
Заключение: използвайте Flexible, когато трябва да запазите място за елемент, но не и да го принуждавате да се разтяга. Това запазва естествените размери на съдържанието при гъвкаво разпределение на оформлението.
FlexFit — изброяване от две стойности: tight и loose. От избора на fit зависи дали дъщерният елемент ще бъде принудително разтегнат до размерите на определеното пространство.
FlexFit.tight: дъщерният елемент получава tight constraints — минималният и максималният размер са равни на определеното пространство. Детето трябва да заеме точно толкова място, колкото Flex-алгоритъмът е определил. Ако детето е по-малко — се разтяга. Ако е по-голямо — се свива. Поведение идентично с Expanded.
FlexFit.loose: дъщерният елемент получава loose constraints — минималният размер е 0, максималният е равен на определеното пространство. Детето може да бъде с произволен размер от 0 до maximum. Ако детето е малко (например Text с кратък низ), то заема естествената си ширина, а останалото място остава празно.
Заключение: FlexFit.loose — избор за текстови блокове и елементи с естествен размер. FlexFit.tight — за строги колонни оформления, където всички елементи трябва да имат еднаква ширина или височина.
Flexible и Expanded изглеждат подобно, но решават различни задачи. Expanded винаги разтяга детето върху цялото налично пространство. Flexible може да остави празно място около детето, ако размерът на съдържанието е по-малък от определения дял.
Сценарий за Flexible: вътре в Row има два бутона. Първият — “Купи” (кратък текст), вторият — “Добави в количката” (дълъг текст). С Expanded двата бутона ще се разтегнат до еднаква ширина и краткият текст ще има огромни полета. С Flexible всеки бутон ще заеме ширината на своя текст, а свободното място ще остане между тях или в краищата.
Сценарий за Expanded: вътре в Column има три карти, които трябва да имат еднаква височина независимо от съдържанието. Expanded равномерно разпределя наличната височина и всяка карта се разтяга до еднакъв размер. Flexible с loose тук не е подходящ — малката карта ще остане малка, нарушавайки единния дизайн.
Заключение: изберете Flexible, когато съдържанието определя размера на елемента и празното място около него е допустимо. Изберете Expanded, когато всички елементи трябва да са с еднакъв размер независимо от съдържанието.
Пример 1 демонстрира основното използване на Flexible с FlexFit.loose в Row.
Row(
children: [
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.amber,
child: const Text('кратък'),
),
),
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.cyan,
child: const Text('дълъг текст за демо'),
),
),
],
)
В примера и двата Flexible с loose fit. Първият контейнер с кратък текст заема естествената си ширина. Вторият с дълъг текст — своята. Row разпределя на всеки половината от наличната ширина, но loose fit позволява на контейнерите да бъдат по-малки и свободното място остава празно между тях.
Пример 2 — сравнение на Flexible с Tight и Loose fit в Column.
Column(
children: [
Flexible(
fit: FlexFit.tight,
child: const Card(
child: ListTile(
title: Text('Tight — разтегнат на пълна височина'),
),
),
),
const SizedBox(
height: 8,
),
Flexible(
fit: FlexFit.loose,
child: const Card(
child: ListTile(
title: Text('Loose — естествена височина'),
),
),
),
],
)
В Column първият Flexible (tight) разтяга Card до половината от наличната височина. Вторият Flexible (loose) — Card заема височина според съдържанието, а останалото пространство остава празно. Визуално се вижда как tight принудително запълва областта, докато loose запазва компактния размер.
Заключение: в производствен код Flexible с loose се прилага за полета на форми, бутони и текстови блокове. Flexible с tight — еквивалент на Expanded, използва се за равномерно разпределение.
Грешка 1: използване на Flexible извън Flex-контейнер. Подобно на Expanded, Flexible хвърля LayoutException, ако не се намира вътре в Row, Column или Flex. Решение: винаги проверявайте родителската верига на елементите.
Грешка 2: объркване между Flexible и Expanded. Разработчиците често използват Expanded, когато е необходим Flexible с loose fit, и обратно. Резултат: Expanded разтяга елемента с кратък текст, създавайки големи празни полета. Решение: ако размерът на елемента може да бъде по-малък от определеното пространство — използвайте Flexible(fit: FlexFit.loose).
Грешка 3: нулев flex-фактор. Flexible с flex=0 се държи като негъвкав елемент, което може да не е очевидно. Разработчикът очаква гъвкаво поведение, но елементът заема минимален размер. Решение: flex трябва да бъде ≥1 за активно разпределение на пространството.
Грешка 4: Flexible вътре в ScrollView без ограничение на размера. Ако Flexible се намира в Column вътре в SingleChildScrollView, scroll-контейнерът дава безкрайно пространство и flex-разпределението не работи. Решение: ограничете размера на scroll-контейнера чрез SizedBox или ConstrainedBox.
Заключение: Flexible изисква същото внимание към родителския контекст като Expanded. Разликата е само във fit — избирайте го съзнателно в зависимост от задачата.
Често задавани въпроси
Expanded — това е Flexible с фиксиран fit=tight. Разликата е, че Expanded има твърда връзка с запълването на цялото налично пространство, докато Flexible може да използва loose fit за запазване на естествения размер на детето.
За бутони с различна дължина на текста използвайте Flexible(fit: FlexFit.loose). Всеки бутон ще заеме ширина според съдържанието и между тях няма да има диспропорция. Expanded ще направи всички бутони с еднаква ширина.
Задайте fit: FlexFit.tight — Flexible ще принуждава детето да запълни цялото определено пространство. В този режим Flexible е напълно идентичен с Expanded по поведение.
Да, ако детето е по-голямо от определеното пространство. Flexible предава constraints с максимален размер равен на дела на Flex-контейнера. Ако детето надвишава този размер, то се свива в рамките на constraints.
Да, Flexible работи с всеки Flex-контейнер, включително Row, Column и основния елемент Flex с произволен direction. Flex позволява задаване на нестандартни посоки чрез mainAxisAlignment и crossAxisAlignment.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също