MediaQuery — об'єкт у Flutter, що надає інформацію про поточне медіа-оточення: розмір екрана, орієнтацію пристрою, щільність пікселів, системні відступи та розмір шрифту. MediaQueryData — контейнер для всіх цих метрик, доступний через MediaQuery.of(context). За даними офіційної документації Flutter (2026), MediaQuery — основа адаптивного дизайну: через нього визначають, чи відображати мобільну або планшетну верстку, розраховувати відступи для safe area та вибирати розміри елементів відносно екрана.
Головне
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 містить десятки властивостей, але найчастіше використовуються ті, що впливають на побудову макету. Розглянемо ключові з них.
MediaQuery.of(context).size повертає об'єкт Size з шириною та висотою екрана в логічних пікселях (device-independent pixels, dip). Ці значення не враховують системні відступи. Для розрахунків адаптивних макетів size — основна метрика: на її основі визначають breakpoints для мобільної, планшетної та десктопної верстки.
ViewPadding — відступи, які система резервує для статус-бара, notch (вирізу на екрані), системної навігаційної панелі та індикатора дому (на iOS). Без урахування цих відступів вміст може опинитися під системними елементами. MediaQuery.of(context).padding повертає EdgeInsets, який потрібно застосовувати як padding до кореневого контейнера сторінки.
ViewInsets — область екрана, перекрита програмною клавіатурою. Для полів введення критично відстежувати viewInsets.bottom, щоб піднімати вміст над клавіатурою. Flutter автоматично обробляє це в scaffold, але для кастомних макетів потрібно використовувати MediaQuery.of(context).viewInsets безпосередньо.
Orientation — портретна (portrait) або ландшафтна (landscape) орієнтація. Визначається порівнянням ширини та висоти: якщо ширина менша за висоту — portrait, інакше — landscape. У production-коді орієнтацію використовують для перемикання між вертикальним та горизонтальним розташуванням елементів.
Висновок: чотири ключові властивості — size, viewPadding, viewInsets та orientation — покривають 90% завдань адаптивного дизайну. Інші властивості (textScaleFactor, platformBrightness, devicePixelRatio) використовуються для специфічних сценаріїв.
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 та врахування доступності.
Приклад 1 демонструє отримання розміру екрана та застосування breakpoints для вибору кількості колонок.
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 для коректного розташування вмісту з урахуванням системних відступів.
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 — визначення орієнтації та зміна розташування елементів.
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-інтерфейсів.
Помилка 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 — область, перекрита системною клавіатурою. Для розрахунку доступного простору без клавіатури: size.height - viewInsets.bottom.
LayoutBuilder дає розміри батьківського контейнера, а не екрана в цілому. Використовуйте LayoutBuilder, коли розміри віджета залежать від доступного простору всередині конкретного батька, а MediaQuery — коли потрібні глобальні метрики екрана.
Автоматично. При повороті пристрою Flutter оновлює MediaQueryData та перебудовує піддерево. Властивість orientation змінюється, і builder всіх підписаних віджетів викликається з новими даними.
Так. Обгортаючи частину віджетів у MediaQuery з перевизначеними даними через MediaQuery.removePadding, MediaQuery.removeViewInsets або MediaQuery з іншими Data. Це застосовується для вбудовування в iframe або preview-режимів.
Для тестів Flutter надає setScreenSize та обгортку MediaQuery у test-оточенні. Для віджет-тестів обгортайте тестований компонент у MaterialApp або MediaQuery з тестовими даними, щоб контролювати розміри екрана.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також