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 — حاشیه‌های سیستمی (نوار وضعیت، ناچ، ناوبری سیستمی)
  • 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 با عرض و ارتفاع صفحه بر حسب پیکسل‌های مستقل از دستگاه (dip) برمی‌گرداند. این مقادیر حاشیه‌های سیستمی را در نظر نمی‌گیرند. برای محاسبات چیدمان‌های تطبیقی، size معیار اصلی است: بر اساس آن breakpoints برای چیدمان موبایل، تبلت و دسکتاپ تعیین می‌شوند.

ViewPadding — حاشیه‌های سیستمی

ViewPadding — حاشیه‌هایی که سیستم برای نوار وضعیت، ناچ (بریدگی صفحه)، پنل ناوبری سیستمی و نشانگر خانه (در iOS) رزرو می‌کند. بدون در نظر گرفتن این حاشیه‌ها، محتوا ممکن است زیر عناصر سیستمی قرار گیرد. MediaQuery.of(context).padding یک EdgeInsets برمی‌گرداند که باید به‌عنوان padding به کانتینر ریشه صفحه اعمال شود.

ViewInsets — ناحیه صفحه‌کلید

ViewInsets — ناحیه صفحه‌ای که توسط صفحه‌کلید نرم‌افزاری پوشانده شده است. برای فیلدهای ورودی، ردیابی viewInsets.bottom بسیار مهم است تا محتوا بالای صفحه‌کلید قرار گیرد. Flutter این را به‌طور خودکار در scaffold مدیریت می‌کند، اما برای چیدمان‌های سفارشی باید مستقیماً از MediaQuery.of(context).viewInsets استفاده کرد.

Orientation — جهت‌گیری دستگاه

Orientation — جهت‌گیری عمودی (portrait) یا افقی (landscape). با مقایسه عرض و ارتفاع تعیین می‌شود: اگر عرض کمتر از ارتفاع باشد — portrait، در غیر این صورت — landscape. در کد تولیدی، از جهت‌گیری برای جابجایی بین چیدمان عمودی و افقی عناصر استفاده می‌شود.

نتیجه: چهار ویژگی کلیدی — 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 نوار وضعیت و ناچ را در نظر می‌گیرد، 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()],
        );
}

در حالت عمودی عناصر به‌صورت عمودی (Column) و در حالت افقی به‌صورت افقی (Row) چیده می‌شوند. این رویکرد بهترین استفاده از فضا را هنگام چرخش دستگاه فراهم می‌کند.

نتیجه: MediaQuery — ابزار اصلی برای ساخت چیدمان‌های تطبیقی است. هنگام توسعه رابط‌های Flutter همیشه حاشیه‌های سیستمی، breakpoints و جهت‌گیری را در نظر بگیرید.

خطاهای رایج هنگام کار با MediaQuery

خطای ۱: فراخوانی MediaQuery.of(context) خارج از زمینه‌ای که MediaQuery تنظیم شده است. اگر ویجت بالاتر از MediaQuery در درخت باشد، فراخوانی منجر به خطای زمان اجرا می‌شود. راه‌حل: همیشه MediaQuery.of(context) را داخل ویجت‌هایی فراخوانی کنید که در MaterialApp یا CupertinoApp پیچیده شده‌اند، جایی که MediaQuery به‌عنوان ویجت ریشه تنظیم شده است.

خطای ۲: فراموش کردن safe area. توسعه‌دهندگان از MediaQuery.size برای قرارگیری عناصر بدون در نظر گرفتن حاشیه‌های سیستمی استفاده می‌کنند. در دستگاه‌های دارای ناچ یا gesture navigation، محتوا زیر نوار وضعیت قرار می‌گیرد. راه‌حل: MediaQuery.of(context).padding را از مختصات موقعیت‌یابی کم کنید.

خطای ۳: وابستگی سخت به اندازه‌ها. استفاده از MediaQuery.of(context).size.width برای تعیین اندازه‌های دقیق عناصر (width: size.width * 0.3) فقط روی دستگاه‌های یک فرم فاکتور کار می‌کند. روی دسکتاپ یا تبلت چیدمان غیرطبیعی به نظر می‌رسد. راه‌حل: از breakpoints به همراه Expanded و Flexible برای چیدمان انعطاف‌پذیر استفاده کنید، نه درصدهای سخت.

خطای ۴: نادیده گرفتن textScaleFactor. وقتی کاربر قلم سیستم را افزایش می‌دهد، رابط ممکن است خراب شود — متن‌ها از مرز کانتینرها خارج می‌شوند. راه‌حل: MediaQuery.of(context).textScaleFactor را بررسی کنید و در مقادیر بالای ۱.۳ چیدمان را به نسخه ساده‌تری با قابلیت پیمایش تغییر دهید.

نتیجه: MediaQuery — ابزاری قدرتمند اما ظریف است. حاشیه‌های سیستمی، جهت‌گیری و تنظیمات دسترسی‌پذیری را در نظر بگیرید تا رابط روی همه دستگاه‌ها به‌درستی نمایش داده شود.

سؤالات متداول

تفاوت MediaQuery.size و MediaQuery.viewInsets چیست؟

MediaQuery.size — اندازه کلی صفحه یا پنجره برنامه بر حسب پیکسل منطقی. MediaQuery.viewInsets — ناحیه پوشیده شده توسط صفحه‌کلید سیستم. برای محاسبه فضای موجود بدون صفحه‌کلید: size.height - viewInsets.bottom.

چه زمانی به جای MediaQuery از LayoutBuilder استفاده کنیم؟

LayoutBuilder اندازه‌های کانتینر والد را می‌دهد، نه کل صفحه. وقتی اندازه‌های ویجت به فضای موجود درون یک والد خاص بستگی دارد از LayoutBuilder استفاده کنید، و وقتی معیارهای سراسری صفحه نیاز است از MediaQuery.

MediaQuery چگونه به تغییر جهت‌گیری واکنش نشان می‌دهد؟

به‌طور خودکار. هنگام چرخش دستگاه، Flutter MediaQueryData را به‌روز می‌کند و زیردرخت را بازسازی می‌کند. ویژگی orientation تغییر می‌کند و builder همه ویجت‌های مشترک با داده‌های جدید فراخوانی می‌شود.

آیا می‌توان MediaQuery را برای بخشی از برنامه تغییر داد؟

بله. با پیچیدن بخشی از ویجت‌ها در MediaQuery با داده‌های بازنویسی‌شده از طریق MediaQuery.removePadding، MediaQuery.removeViewInsets یا MediaQuery با Data دیگر. این برای جاسازی در iframe یا حالت‌های پیش‌نمایش استفاده می‌شود.

MediaQuery چگونه بر تست تأثیر می‌گذارد؟

برای تست‌ها، Flutter setScreenSize و پوشش MediaQuery را در محیط تست فراهم می‌کند. برای ویجت تست‌ها، کامپوننت مورد آزمایش را در MaterialApp یا MediaQuery با داده‌های تست بپیچید تا اندازه‌های صفحه را کنترل کنید.

خلاصه

  • MediaQuery — منبع مرکزی معیارهای صفحه در Flutter: اندازه، جهت‌گیری، حاشیه‌ها و تراکم
  • MediaQuery.of(context) — روش استاندارد دسترسی به داده‌ها از طریق BuildContext فعلی
  • ViewPadding برای در نظر گرفتن safe area در دستگاه‌های دارای ناچ و gesture navigation اجباری است
  • Breakpoints (600, 900dp) — اساس طراحی تطبیقی از طریق MediaQuery.size.width
  • Orientation هنگام چرخش دستگاه چیدمان عناصر را تغییر می‌دهد
  • textScaleFactor تنظیمات دسترسی‌پذیری سیستم را برای مقیاس‌بندی قلم در نظر می‌گیرد
  • توصیه: هنگام ساخت چیدمان‌های ریشه همیشه viewPadding و viewInsets را بررسی کنید

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید