MediaQuery هو كائن في Flutter يوفر معلومات عن البيئة الإعلامية الحالية: حجم الشاشة، اتجاه الجهاز، كثافة البكسل، هوامش النظام، وحجم الخط. MediaQueryData عبارة عن حاوية لجميع هذه المقاييس، يمكن الوصول إليها عبر MediaQuery.of(context). وفقاً لوثائق Flutter الرسمية (2026)، MediaQuery هو أساس التصميم المتجاوب: من خلاله يتم تحديد ما إذا كان سيتم عرض تخطيط الجوال أو الجهاز اللوحي، حساب هوامش المنطقة الآمنة، واختيار أحجام العناصر بالنسبة للشاشة.
الرئيسية
MediaQuery هو عنصر واجهة (widget) وفئة في 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 بعرض وارتفاع الشاشة بالبكسل المستقل عن الجهاز (dip). هذه القيم لا تأخذ في الاعتبار هوامش النظام. لحسابات التخطيط المتجاوب، size هو المقياس الأساسي: يحدد نقاط الفصل لتخطيطات الجوال والجهاز اللوحي وسطح المكتب.
ViewPadding هي الهوامش التي يحجزها النظام لشريط الحالة، notch (القطع في الشاشة)، لوحة التنقل النظامية، ومؤشر الصفحة الرئيسية (على iOS). بدون مراعاة هذه الهوامش، قد يظهر المحتوى تحت عناصر النظام. MediaQuery.of(context).padding يعيد EdgeInsets يجب تطبيقه كحشية (padding) للحاوية الجذرية للصفحة.
ViewInsets هي منطقة الشاشة المغطاة بلوحة المفاتيح البرمجية. لحقول الإدخال، من الضروري مراقبة viewInsets.bottom لرفع المحتوى فوق لوحة المفاتيح. Flutter يتعامل مع هذا تلقائياً في scaffold، لكن للتخطيطات المخصصة يجب استخدام MediaQuery.of(context).viewInsets مباشرة.
Orientation — الاتجاه العمودي (portrait) أو الأفقي (landscape). يتم تحديده بمقارنة العرض والارتفاع: إذا كان العرض أقل من الارتفاع — portrait، وإلا — landscape. في كود الإنتاج، يُستخدم الاتجاه للتبديل بين الترتيب الرأسي والأفقي للعناصر.
الخلاصة: أربع خصائص رئيسية — size، viewPadding، viewInsets، و orientation — تغطي 90% من مهام التصميم المتجاوب. الخصائص المتبقية (textScaleFactor، platformBrightness، devicePixelRatio) تُستخدم لسيناريوهات محددة.
MediaQuery هو أساس التصميم المتجاوب في Flutter. من خلاله يتم تحديد نقاط الفصل، تبديل التخطيط حسب حجم الشاشة، وضبط الهوامش للأجهزة المختلفة.
سيناريو نموذجي: تطبيق جوال يحتاج إلى عرض قائمة منتجات. على الهاتف (عرض < 600dp) — عمود واحد. على الجهاز اللوحي (عرض 600–900dp) — عمودان. على سطح المكتب (عرض > 900dp) — ثلاثة أعمدة. MediaQuery.of(context).size.width يتيح اختيار عدد الأعمدة ديناميكياً دون شاشة منفصلة لكل عامل شكل.
السيناريو الثاني: مراعاة هوامش الإيماءات النظامية على الأجهزة الحديثة. على أجهزة iPhone مع Dynamic Island أو Android مع التنقل بالإيماءات، تستهلك هوامش النظام جزءاً من الشاشة. MediaQuery.of(context).padding يعيد القيم الصحيحة لكل نوع جهاز، و Scaffold يطبقها تلقائياً عبر body. للعناصر المخصصة، يجب تمرير padding من MediaQuery بشكل صريح.
السيناريو الثالث: التكيف مع إعدادات إمكانية الوصول للنظام. MediaQuery.of(context).textScaleFactor يوضح مقدار زيادة المستخدم لحجم الخط في الإعدادات. عند textScaleFactor > 1.3، قد ينكسر التخطيط — النصوص الطويلة تتجاوز حدود البطاقات. يجب أن تأخذ التخطيطات المتجاوبة هذا في الاعتبار، وإذا لزم الأمر، التبديل إلى تخطيط أبسط.
الخلاصة: MediaQuery ليس مجرد مصدر للمقاييس، بل أداة لبناء واجهات متجاوبة حقاً. استخدمه لنقاط الفصل والمنطقة الآمنة واعتبارات إمكانية الوصول.
مثال 1 يوضح كيفية الحصول على حجم الشاشة وتطبيق نقاط الفصل لاختيار عدد الأعمدة.
int getColumnCount(BuildContext context) {
final width = MediaQuery.of(context).size.width;
if (width > 900) return 3;
if (width > 600) return 2;
return 1;
}
المثال أعلاه يظهر دالة لاختيار عدد الأعمدة بناءً على عرض الشاشة. نقاط الفصل 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)، يتم ترتيب العناصر عمودياً (Column)؛ في الوضع الأفقي (landscape)، أفقياً (Row). هذا النهج يعطي أفضل استغلال للمساحة عند تدوير الجهاز.
الخلاصة: MediaQuery هو الأداة الرئيسية لبناء التخطيطات المتجاوبة. دائماً ضع في اعتبارك هوامش النظام ونقاط الفصل والاتجاه عند تطوير واجهات Flutter.
الخطأ 1: استدعاء MediaQuery.of(context) خارج سياق تم فيه إعداد MediaQuery. إذا كان العنصر أعلى من MediaQuery في الشجرة، يؤدي الاستدعاء إلى خطأ في وقت التشغيل. الحل: دائماً استدعاء MediaQuery.of(context) داخل عناصر مغلفة بـ MaterialApp أو CupertinoApp، حيث يكون MediaQuery مضبوطاً كعنصر جذر.
الخطأ 2: نسيان المنطقة الآمنة. يستخدم المطورون MediaQuery.size لتحديد موضع العناصر دون مراعاة هوامش النظام. على الأجهزة ذات notch أو التنقل بالإيماءات، يظهر المحتوى تحت شريط الحالة. الحل: طرح MediaQuery.of(context).padding من إحداثيات التموضع.
الخطأ 3: الربط الجامد بالأحجام. استخدام MediaQuery.of(context).size.width لتحديد أحجام دقيقة للعناصر (width: size.width * 0.3) يعمل فقط على الأجهزة من نفس عامل الشكل. على سطح المكتب أو الجهاز اللوحي، يبدو التخطيط غير طبيعي. الحل: استخدام نقاط الفصل مع 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 ويتم استدعاء مُنشئ جميع العناصر المشتركة بالبيانات الجديدة.
نعم. عن طريق تغليف جزء من العناصر في MediaQuery ببيانات معدلة عبر MediaQuery.removePadding، MediaQuery.removeViewInsets أو MediaQuery ببيانات أخرى. يُستخدم هذا للتضمين في iframes أو أوضاع المعاينة.
للاختبار، يوفر Flutter setScreenSize وغلاف MediaQuery في بيئة الاختبار. لاختبارات العناصر، قم بتغليف المكون قيد الاختبار في MaterialApp أو MediaQuery ببيانات اختبار للتحكم في أبعاد الشاشة.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.