Какие виджеты Flutter позволяют создавать адаптивный интерфейс под разные размеры экранов?

«Какие виджеты Flutter позволяют создавать адаптивный интерфейс под разные размеры экранов?» — вопрос из категории UI и вёрстка, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для создания адаптивных интерфейсов во Flutter я использую комбинацию встроенных виджетов и определенных практик. Вот основные инструменты:

  1. MediaQuery — отправная точка для получения метрик устройства.

    final size = MediaQuery.of(context).size;
    final isPortrait = size.height > size.width;
    final isTablet = size.shortestSide > 600; // Эмпирическое правило для планшета
  2. LayoutBuilder — ключевой виджет для создания layout, который зависит от доступных ограничений (constraints) родителя, а не от абсолютных размеров экрана.

    LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > 1024) {
          return DesktopLayout();
        } else if (constraints.maxWidth > 600) {
          return TabletLayout();
        } else {
          return MobileLayout();
        }
      },
    )
  3. Flexible и Expanded — для создания гибких макетов внутри Row и Column. Expanded заставляет дочерний виджет заполнить всё доступное пространство, а Flexible позволяет задать коэффициент гибкости (flex).

  4. Wrap — автоматически переносит дочерние виджеты на следующую строку или столбец, если не хватает места. Отлично подходит для списков тегов или фильтров.

  5. AspectRatio — принудительно задает соотношение сторон дочернему виджету (например, для баннеров или изображений).

    AspectRatio(
      aspectRatio: 16 / 9,
      child: Image.network('...'),
    )
  6. FractionallySizedBox — задает размеры в долях (процентах) от доступного пространства.

    FractionallySizedBox(
      widthFactor: 0.8, // Займет 80% ширины родителя
      child: ElevatedButton(...),
    )
  7. OrientationBuilder — реагирует на изменение ориентации устройства.

Моя типичная стратегия: Я начинаю с мобильного дизайна, а затем, используя LayoutBuilder и проверки на maxWidth, добавляю адаптацию для планшетов и десктопов. Часто я выношу логику определения типа layout (мобильный/планшет/десктоп) в отдельный провайдер или утилитный класс, чтобы не дублировать её по всему приложению. Для очень сложных адаптивных систем можно рассмотреть пакеты вроде responsive_framework или flutter_screenutil, но в большинстве случаев встроенных средств Flutter более чем достаточно.