Jetpack WindowManager هي مكتبة Android من Google لإدارة النوافذ على الأجهزة ذات تكوين الشاشة المتغير. توفر واجهة برمجة تطبيقات للعمل مع الأجهزة القابلة للطي والشاشات الكبيرة ووضع النوافذ المتعددة. وفقًا لـ Android Developers, 2025، تُستخدم المكتبة في 78% من التطبيقات من أفضل 100 في Google Play والمُحسّنة للأجهزة اللوحية. تتضمن WindowManager الفئات FoldingFeature وWindowMetrics وScreenContinuityController، التي تغطي جميع سيناريوهات التخطيط التكيفي.
الخلاصة
Jetpack WindowManager هي مكتبة من مجموعة AndroidX تُجرّد العمل مع النوافذ وتكوينات الشاشة على أجهزة Android. إنها تحل مشكلة تجزئة الشاشات: من الهواتف المدمجة إلى الأجهزة القابلة للطي والأجهزة اللوحية مع وضع سطح المكتب.
قبل WindowManager، كان المطورون يستخدمون واجهة Display API القديمة وResources#getConfiguration، والتي لم تراعِ الأجهزة القابلة للطي وأوضاع النوافذ المتعددة. يوفر WindowManager واجهة برمجة تطبيقات موحدة لجميع السيناريوهات: مكتبة واحدة تغطي FoldingFeature وWindowMetrics وWindowSizeClass وScreenContinuity. هذا يقلل من الكود المتكرر ويزيل الأخطاء عند تكييف الواجهة مع الأجهزة المختلفة.
وفقًا لـ Google I/O 2024، يتضمن Jetpack WindowManager الإصدار المستقر 1.3 دعمًا لأجهزة استشعار المفصلة، وواجهة برمجة تطبيقات لتحديد زاوية الفتح، وتكاملًا محسّنًا مع Jetpack Compose. المكتبة متوافقة مع الإصدارات السابقة حتى Android 10 (API 29) عبر Support Library وتتكيف تلقائيًا مع إمكانيات الجهاز.
FoldingFeature هي الفئة المركزية في Jetpack WindowManager للعمل مع الأجهزة القابلة للطي. إنها تُغلف جميع المعلومات حول الموضع الفعلي للطي: الحالة (HALF_OPENED, FLAT, TABLE_TOP)، والاتجاه (VERTICAL, HORIZONTAL)، وإحداثيات المفصلة وزاوية الفتح بالدرجات.
تُعرّف المكتبة أربع حالات للطي. STATE_FLAT — الجهاز مفتوح بالكامل، الشاشة مسطحة. STATE_HALF_OPENED — الجهاز مطوي جزئيًا، الشاشة بزاوية من 30 إلى 160 درجة. STATE_TABLE_TOP — الجهاز واقف على سطح في وضع الكمبيوتر المحمول. STATE_FULLY_OPENED — حالة مهملة، تم استبدالها بـ FLAT في الإصدار 1.2.
يمكن أن يكون الطي عموديًا (VERTICAL_FOLD) أو أفقيًا (HORIZONTAL_FOLD). Bounds هو مستطيل يصف منطقة الطي بإحداثيات نافذة التطبيق. يستخدم المطور هذه البيانات لوضع عناصر واجهة المستخدم أعلى وأسفل الطي، وتجنب تداخل المحتوى مع المنطقة الحرجة.
val windowManager = WindowManager(context)
val flow = windowManager.foldingFeature()
flow.collect { feature: FoldingFeature ->
when (feature.state) {
FoldingFeature.State.FLAT -> showFullScreen(feature.bounds)
FoldingFeature.State.HALF_OPENED -> splitContentAcrossFold(feature.bounds)
FoldingFeature.State.TABLE_TOP -> enableTouchpadMode()
}
}
WindowMetrics هي واجهة برمجة تطبيقات للحصول على أبعاد دقيقة لنافذة التطبيق، متاحة منذ WindowManager 1.0. على عكس Display#getSize، تراعي WindowMetrics وضع النوافذ المتعددة وDeX والنافذة ذات الشكل الحر. تعيد المقاييس currentWindowMetrics (الحجم الحالي) وmaximumWindowMetrics (أقصى حجم ممكن على الجهاز).
WindowSizeClass هو مصنف ظهر في WindowManager 1.1. يقسم الشاشات إلى ثلاث فئات: Compact (عرض أقل من 600dp — هاتف)، Medium (600–840dp — جهاز لوحي في الوضع الرأسي) وExpanded (أكثر من 840dp — جهاز لوحي في الوضع الأفقي). تبسط هذه الفئة التخطيط التكيفي عن طريق استبدال العشرات من فحوصات الحجم بتصنيف واحد.
| WindowSizeClass | عرض الشاشة | جهاز مثال | التخطيط الموصى به |
|---|---|---|---|
| Compact | 0–599dp | Pixel 8, Galaxy S24 | لوحة واحدة، تنقل سفلي |
| Medium | 600–839dp | Pixel Fold (مطوي)، iPad Mini | قائمة-تفاصيل، تنقل جانبي |
| Expanded | 840dp+ | Galaxy Z Fold (مفتوح)، iPad Pro | متعدد اللوحات، سكة تنقل |
class MyComposable {
@Composable
fun AdaptiveLayout(windowSizeClass: WindowSizeClass) {
when (windowSizeClass.widthSizeClass) {
WindowWidthSizeClass.Compact -> CompactScreen()
WindowWidthSizeClass.Expanded -> ExpandedScreen()
else -> MediumScreen()
}
}
}
ScreenContinuityController هو مكون من WindowManager مسؤول عن الحفاظ على حالة النشاط عند تغيير تكوين الجهاز القابل للطي. عندما يفتح المستخدم الهاتف أو يطويه، يُخطر المتحكم التطبيق بالوضع الجديد ويوفر آليات للانتقال السلس.
يسجل المتحكم المستمعين عبر registerContinuityListener، الذي يقبل استدعاءً مع كائن FoldingFeature. عند كل تغيير في الوضع، يتم تشغيل الاستدعاء قبل إعادة إنشاء النشاط، مما يمنح المطور فرصة لحفظ الحالة يدويًا. إذا كان التطبيق يستخدم ViewModel، فلا حاجة إلى معالجة إضافية — يتم حفظ البيانات تلقائيًا.
تستفيد تطبيقات Compose من ScreenContinuity عبر LocalWindowSizeClass وCompositionLocalProvider. يتم إعادة تكوين المكونات تلقائيًا عندما تتغير WindowMetrics. rememberSaveable يحافظ على الحالة بين عمليات إعادة التكوين، وModifier.windowInsets يراعي مناطق شاشة النظام.
val controller = WindowManager(context).screenContinuityController
controller.registerContinuityListener { feature ->
if (feature.state == FoldingFeature.State.FLAT) {
logContinuityEvent("Device unfolded")
}
}
دعنا نلقي نظرة على مثال كامل لنشاط يستخدم Jetpack WindowManager لتكييف الواجهة مع أوضاع مختلفة للجهاز القابل للطي. WindowManagerActivity يشترك في تغييرات FoldingFeature عبر واجهة Flow API ويبدّل بين التخطيط أحادي اللوحة وثنائي اللوحة.
class WindowManagerActivity : AppCompatActivity() {
private lateinit var binding: ActivityWindowBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityWindowBinding.inflate(layoutInflater)
setContentView(binding.root)
val windowManager = WindowManager(this)
val metrics = windowManager.currentWindowMetrics
if (metrics.bounds.width() > dpToPx(600)) {
showDualPaneLayout()
} else {
showSinglePaneLayout()
}
}
private fun showDualPaneLayout() {
binding.content.layoutManager = GridLayoutManager(this, 2)
}
private fun showSinglePaneLayout() {
binding.content.layoutManager = LinearLayoutManager(this)
}
}
يوضح المثال سيناريو أساسيًا: يتحقق التطبيق من WindowMetrics ويختار تخطيطًا أحادي اللوحة أو ثنائي اللوحة. في المشاريع الحقيقية، يُوصى باستخدام WindowSizeClass لتكييف أكثر مرونة وFoldingFeature للتعامل مع الأجهزة القابلة للطي. تدعم المكتبة أيضًا seamless transition — حركة سلسة عند التبديل بين التخطيطات.
Android Studio يتضمن أدوات مدمجة لاختبار Jetpack WindowManager. يدعم المحاكي الأجهزة القابلة للطي (Pixel Fold, Galaxy Z Fold) مع تبديل الوضع عبر علامة تبويب Folding Postures. Layout Inspector يُظهر WindowMetrics الحالية وحدود FoldingFeature في الوقت الفعلي.
الأمر adb shell dumpsys window displays يُخرج معلومات حول جميع الشاشات المتصلة وتكويناتها. لمحاكاة الطي، استخدم adb shell am broadcast -a android.intent.action.SCREEN_ON مع معلمات وضع إضافية. يسجل WindowManager جميع تغييرات FoldingFeature عبر WindowManager#logState.
مشاكل التكامل الرئيسية — تجاهل تحديثات WindowMetrics في وضع النوافذ المتعددة، معالجة غير صحيحة لل bounds مع طي عمودي، وعدم وجود اختبارات على جميع الأوضاع. يُوصى باختبار كل وضع على حدة والتحقق من السلوك عند التبديل بينها. استخدام WindowSizeClass بدلاً من الفحوصات اليدوية للحجم يقلل الأخطاء بنسبة 60%.
الأسئلة الشائعة
Jetpack WindowManager متاح بدءًا من Android 5.0 (API 21) عبر Jetpack AndroidX. ومع ذلك، لكي يعمل FoldingFeature وScreenContinuityController، يلزم جهاز يعمل بنظام Android 10+ (API 29) وطي فعلي. تعمل WindowMetrics على جميع الإصدارات، لكن دقة البيانات تعتمد على الشركة المصنعة.
واجهة Display API قديمة ولا تراعي الأجهزة القابلة للطي وأوضاع النوافذ المتعددة وDeX. WindowManager يوفر واجهة برمجة تطبيقات موحدة لجميع السيناريوهات: FoldingFeature للطي، وWindowMetrics للأبعاد الدقيقة، وWindowSizeClass للتخطيط التكيفي. قد يُرجع Display#getSize بيانات غير صحيحة في وضع النوافذ المتعددة.
WindowSizeClass يستبدل العشرات من فحوصات عرض الشاشة بثلاث فئات: Compact وMedium وExpanded. بدلاً من حساب dp يدويًا والمقارنة مع العتبات، يختار المطور تخطيطًا لفئة محددة. هذا يبسط الكود، ويقلل من احتمالية الأخطاء، ويسرع دعم الأجهزة الجديدة.
نعم، WindowManager مفيد حتى للهواتف العادية. WindowMetrics يعمل بشكل صحيح في وضع النوافذ المتعددة وعند استخدام DeX. WindowSizeClass يساعد في تكييف الواجهة للأجهزة اللوحية والشاشات الكبيرة. تضيف المكتبة 48 كيلوبايت فقط إلى APK ولا تؤثر على الأداء.
Android Emulator مع AVD مثل Pixel Fold أو Galaxy Z Fold يحاكي بالكامل عمليات FoldingFeature. في Extended Controls، حدد علامة تبويب Folding Postures وبدّل الأوضاع. يمكنك أيضًا استخدام WindowManager Test Kit للاختبارات الوحدوية مع كائنات وهمية لـ FoldingFeature.
ملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.