MediaQuery — що це, принцип роботи та адаптивні макети

Автор: IT Sectr Опубліковано: 2026-07-03 Час читання: 7 хв

MediaQuery — об'єкт у Flutter, що надає інформацію про поточне медіа-оточення: розмір екрана, орієнтацію пристрою, щільність пікселів, системні відступи та розмір шрифту. MediaQueryData — контейнер для всіх цих метрик, доступний через MediaQuery.of(context). За даними офіційної документації Flutter (2026), MediaQuery — основа адаптивного дизайну: через нього визначають, чи відображати мобільну або планшетну верстку, розраховувати відступи для safe area та вибирати розміри елементів відносно екрана.

Головне

  • MediaQuery — клас для отримання метрик екрана: розмір, орієнтація, щільність, відступи
  • MediaQuery.of(context) — основний спосіб доступу до даних через BuildContext
  • Size (MediaQuery.size) — ширина та висота екрана в логічних пікселях
  • ViewPadding — системні відступи (статус-бар, notch, системна навігація)
  • Orientation — портретна або ландшафтна орієнтація пристрою

Що таке MediaQuery

MediaQuery — це віджет і клас Flutter, який надає дані про медіа-оточення додатку. MediaQuery обгортає весь додаток у кореневий віджет MaterialApp або CupertinoApp, і будь-який дочірній віджет може отримати доступ до цих даних через MediaQuery.of(context).

Коли Flutter запускає додаток, він створює екземпляр MediaQueryData, що містить усі метрики поточного пристрою. Ці дані оновлюються автоматично при змінах: повороті пристрою, зміні розміру вікна (на десктопі), появі клавіатури або зміні системних налаштувань доступності. MediaQuery перебудовує піддерево віджетів при будь-якій зміні даних, забезпечуючи реактивну адаптацію інтерфейсу.

MediaQueryData включає: size (розмір екрана), devicePixelRatio (щільність пікселів), textScaleFactor (масштаб шрифту з системних налаштувань), viewInsets (область, перекрита клавіатурою), viewPadding (системні відступи), orientation (орієнтація) та platformBrightness (світла або темна тема).

Висновок: MediaQuery — центральне джерело інформації про пристрій у Flutter. Доступ до MediaQuery.of(context) — перший крок у побудові будь-якого адаптивного інтерфейсу.

Основні властивості MediaQueryData

MediaQueryData містить десятки властивостей, але найчастіше використовуються ті, що впливають на побудову макету. Розглянемо ключові з них.

Size — розмір екрана

MediaQuery.of(context).size повертає об'єкт Size з шириною та висотою екрана в логічних пікселях (device-independent pixels, dip). Ці значення не враховують системні відступи. Для розрахунків адаптивних макетів size — основна метрика: на її основі визначають breakpoints для мобільної, планшетної та десктопної верстки.

ViewPadding — системні відступи

ViewPadding — відступи, які система резервує для статус-бара, notch (вирізу на екрані), системної навігаційної панелі та індикатора дому (на iOS). Без урахування цих відступів вміст може опинитися під системними елементами. MediaQuery.of(context).padding повертає EdgeInsets, який потрібно застосовувати як padding до кореневого контейнера сторінки.

ViewInsets — область клавіатури

ViewInsets — область екрана, перекрита програмною клавіатурою. Для полів введення критично відстежувати viewInsets.bottom, щоб піднімати вміст над клавіатурою. Flutter автоматично обробляє це в scaffold, але для кастомних макетів потрібно використовувати MediaQuery.of(context).viewInsets безпосередньо.

Orientation — орієнтація пристрою

Orientation — портретна (portrait) або ландшафтна (landscape) орієнтація. Визначається порівнянням ширини та висоти: якщо ширина менша за висоту — portrait, інакше — landscape. У production-коді орієнтацію використовують для перемикання між вертикальним та горизонтальним розташуванням елементів.

Висновок: чотири ключові властивості — size, viewPadding, viewInsets та orientation — покривають 90% завдань адаптивного дизайну. Інші властивості (textScaleFactor, platformBrightness, devicePixelRatio) використовуються для специфічних сценаріїв.

Використання MediaQuery для адаптивних макетів

MediaQuery — основа адаптивного дизайну у Flutter. Через нього визначають breakpoints, перемикають layout залежно від розміру екрана та коригують відступи для різних пристроїв.

Типовий сценарій: мобільний додаток повинен відображати список товарів. На телефоні (ширина < 600dp) — одна колонка. На планшеті (ширина 600–900dp) — дві колонки. На десктопі (ширина > 900dp) — три колонки. MediaQuery.of(context).size.width дозволяє динамічно вибирати кількість колонок без окремого екрана для кожного форм-фактора.

Другий сценарій: урахування system gesture insets на сучасних пристроях. На iPhone з Dynamic Island або Android з gesture navigation системні відступи з'їдають частину екрана. MediaQuery.of(context).padding повертає коректні значення для кожного типу пристрою, і Scaffold автоматично застосовує їх через body. Для кастомних віджетів потрібно явно передавати padding з MediaQuery.

Третій сценарій: адаптація під системні налаштування доступності. MediaQuery.of(context).textScaleFactor показує, наскільки користувач збільшив шрифт у налаштуваннях. При textScaleFactor > 1.3 макет може зламатися — довгі тексти виходять за межі карток. Адаптивні макети повинні враховувати це та, за потреби, перемикатися на простішу верстку.

Висновок: MediaQuery — не просто джерело метрик, а інструмент для побудови справді адаптивних інтерфейсів. Використовуйте його для breakpoints, safe area та врахування доступності.

Приклади коду з MediaQuery

Приклад 1 демонструє отримання розміру екрана та застосування breakpoints для вибору кількості колонок.

dart
int getColumnCount(BuildContext context) {
  final width = MediaQuery.of(context).size.width;
  if (width > 900) return 3;
  if (width > 600) return 2;
  return 1;
}

Приклад вище показує функцію вибору кількості колонок на основі ширини екрана. Breakpoints 600 і 900 відповідають загальноприйнятим стандартам Material Design для телефонів, планшетів і десктопа.

Приклад 2 — використання MediaQuery з viewPadding для коректного розташування вмісту з урахуванням системних відступів.

dart
Widget build(BuildContext context) {
  final padding = MediaQuery.of(context).padding;

  return Padding(
    padding: EdgeInsets.only(
      top: padding.top,
      left: padding.left,
      right: padding.right,
    ),
    child: const MyContent(),
  );
}

У цьому прикладі padding обгортає вміст у Padding, використовуючи системні відступи. top враховує статус-бар і notch, left/right — безпечні зони. bottom не включений, оскільки Scaffold зазвичай сам обробляє нижню навігацію.

Приклад 3 — визначення орієнтації та зміна розташування елементів.

dart
Widget build(BuildContext context) {
  final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;

  return isPortrait
      ? const Column(
          children: [HeaderBanner(), ContentList()],
        )
      : const Row(
          children: [HeaderBanner(), ContentList()],
        );
}

У portrait mode елементи розташовані вертикально (Column), у landscape — горизонтально (Row). Такий підхід дає найкраще використання простору при повороті пристрою.

Висновок: MediaQuery — основний інструмент для побудови адаптивних макетів. Завжди враховуйте системні відступи, breakpoints та орієнтацію при розробці Flutter-інтерфейсів.

Типові помилки при роботі з MediaQuery

Помилка 1: виклик MediaQuery.of(context) поза контекстом, де встановлено MediaQuery. Якщо віджет знаходиться вище MediaQuery у дереві, виклик призводить до помилки часу виконання. Рішення: завжди викликати MediaQuery.of(context) всередині віджетів, обгорнутих MaterialApp або CupertinoApp, де MediaQuery встановлений кореневим віджетом.

Помилка 2: забудькуватість про safe area. Розробники використовують MediaQuery.size для розташування елементів без урахування системних відступів. На пристроях з notch або gesture navigation вміст опиняється під статус-баром. Рішення: віднімати MediaQuery.of(context).padding з координат позиціонування.

Помилка 3: жорстка прив'язка до розмірів. Використання MediaQuery.of(context).size.width для задання точних розмірів елементів (width: size.width * 0.3) працює тільки на пристроях одного форм-фактора. На десктопі або планшеті макет виглядає неприродно. Рішення: використовувати breakpoints у поєднанні з Expanded та Flexible для гнучкого макету, а не жорсткі відсотки.

Помилка 4: ігнорування textScaleFactor. При збільшенні системного шрифту користувачем інтерфейс може зламатися — тексти виходять за межі контейнерів. Рішення: перевіряти MediaQuery.of(context).textScaleFactor і при значеннях вище 1.3 перемикати макет на простішу верстку з прокруткою.

Висновок: MediaQuery — потужний, але тонкий інструмент. Враховуйте системні відступи, орієнтацію та налаштування доступності, щоб інтерфейс виглядав коректно на всіх пристроях.

Часті запитання

Чим відрізняється MediaQuery.size від MediaQuery.viewInsets?

MediaQuery.size — загальний розмір екрана або вікна додатку в логічних пікселях. MediaQuery.viewInsets — область, перекрита системною клавіатурою. Для розрахунку доступного простору без клавіатури: size.height - viewInsets.bottom.

Коли використовувати LayoutBuilder замість MediaQuery?

LayoutBuilder дає розміри батьківського контейнера, а не екрана в цілому. Використовуйте LayoutBuilder, коли розміри віджета залежать від доступного простору всередині конкретного батька, а MediaQuery — коли потрібні глобальні метрики екрана.

Як MediaQuery реагує на зміну орієнтації?

Автоматично. При повороті пристрою Flutter оновлює MediaQueryData та перебудовує піддерево. Властивість orientation змінюється, і builder всіх підписаних віджетів викликається з новими даними.

Чи можна змінити MediaQuery для частини додатку?

Так. Обгортаючи частину віджетів у MediaQuery з перевизначеними даними через MediaQuery.removePadding, MediaQuery.removeViewInsets або MediaQuery з іншими Data. Це застосовується для вбудовування в iframe або preview-режимів.

Як MediaQuery впливає на тестування?

Для тестів Flutter надає setScreenSize та обгортку MediaQuery у test-оточенні. Для віджет-тестів обгортайте тестований компонент у MaterialApp або MediaQuery з тестовими даними, щоб контролювати розміри екрана.

Підсумки

  • MediaQuery — центральне джерело метрик екрана у Flutter: розмір, орієнтація, відступи та щільність
  • MediaQuery.of(context) — стандартний спосіб доступу до даних через поточний BuildContext
  • ViewPadding обов'язковий для врахування safe area на пристроях з notch і gesture navigation
  • Breakpoints (600, 900dp) — основа адаптивного дизайну через MediaQuery.size.width
  • Orientation перемикає розташування елементів при повороті пристрою
  • textScaleFactor враховує системні налаштування доступності для масштабування шрифту
  • Рекомендація: завжди перевіряйте viewPadding та viewInsets при побудові кореневих макетів

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також