تنسيق وضع "الشاشة المسطحة" باستخدام Grid وmediaQuery

رمز التقييم بأربع نجوم

يقسّم وضع "الكمبيوتر اللوحي" على الأجهزة القابلة للطي شاشة واحدة إلى منطقتَي عرض وظيفيتَين يفصل بينهما الطي المادي (أو المفصلة). يتيح لك وضع "الكمبيوتر اللوحي" وضع المحتوى الرئيسي لتطبيقك (مثل مشغّل فيديو أو لوحة ألعاب) في النصف العلوي، بينما يتم وضع العناصر التفاعلية (مثل عناصر التحكّم في الوسائط أو لوحات التحكّم) في النصف السفلي.

جهاز قابل للطي في وضع سطح الطاولة يعرض محتوى فيديو على الشاشة العلوية وعناصر التحكّم في التشغيل على الشاشة السفلية
الشكل 1. يقسّم وضع "الكمبيوتر اللوحي" المحتوى وعناصر التحكّم التفاعلية على طول الطي المادي.

أفضل الممارسات

لإضافة دعم وضع "الكمبيوتر اللوحي" إلى تطبيقك، استخدِم واجهة برمجة التطبيقات Grid لتحديد تنسيق يتضمّن صفَّين وعمودًا واحدًا، وطبِّق طلب البحث عن الوسائط في وضع "الكمبيوتر اللوحي".

  • رصد وضع الشاشة المسطحة بشكل تفاعلي: استخدِم الدالة المركّبة mediaQuery لمراقبة حالة الأجهزة. عند طيّ الجهاز في وضع "الكمبيوتر اللوحي" (windowPosture == Posture.Tabletop)، يمكنك تغيير تنسيقك ديناميكيًا بدون الحاجة إلى إعادة تشغيل النشاط أو التعامل مع دورة الحياة المعقّدة.
  • تنظيم التنسيقات باستخدام Grid: عند استخدام وضع "الكمبيوتر اللوحي"، استخدِم واجهة برمجة التطبيقات Grid (2 rows و1 column) لفصل المحتوى المرئي الأساسي بشكل واضح في الصف العلوي فوق الطي وعناصر التحكّم التفاعلية في الصف السفلي تحت الطي.
  • الاستفادة من الفهرسة الضمنية على المحور z للطبقات: في الأوضاع العادية (غير وضع "الكمبيوتر اللوحي")، يمكنك تعيين معرّفات مناطق متعددة للخلية نفسها لتراكب عناصر التحكّم فوق المشغّل. تعرض Grid العناصر تلقائيًا من الخلف إلى الأمام بترتيب إعلانها.
  • توفير انتقالات سلسة: تأكَّد من الاحتفاظ بالحالة ومواضع التمرير عند الانتقال بين التنسيقات العادية بملء الشاشة ووضع "الكمبيوتر اللوحي".

المكوّنات

  • Grid: حاوية تنسيق تكيُّفي تتيح لك وضع العناصر في صفوف وأعمدة قابلة للإعداد، وهي مثالية لتقسيم المحتوى على مناطق شاشة مختلفة.
  • mediaQuery: واجهة برمجة تطبيقات Jetpack Compose تُستخدَم للاستعلام عن وضع النافذة الحالي للتطبيق وفئات الحجم وخصائص الأجهزة مباشرةً ضِمن الدوال البرمجية.

الخطوات

استخدِم mediaQuery() للاستعلام عن وضع الجهاز. عندما يكون الجهاز في وضع "الكمبيوتر اللوحي"، رتِّب محتوى تطبيقك في شبكة عمودية تتضمّن صفَّين وعمودًا واحدًا، مع التأكّد من بقاء المحتوى الأساسي في الأعلى وبقاء عناصر التحكّم في الأسفل لتسهيل الوصول إليها.

‫1. تحديد إعدادات Grid لوضع "الكمبيوتر اللوحي"

ضِمن دالة برمجية، حدِّد معرّفات مناطق التنسيق باستخدام تعداد، واضبط كتل GridConfigurationScope للأوضاع التلقائية ووضع "الكمبيوتر اللوحي".

في defaultConfig، يتم تعيين كلتا المنطقتَين للخلية نفسها (row = 1, column = 1). تستخدِم Grid الفهرسة الضمنية على المحور z حيث يتم عرض الدوال البرمجية التي تم الإعلان عنها لاحقًا في التنسيق فوق الدوال البرمجية السابقة، ما يسمح لوحدة التحكّم بتراكب المشغّل بدون تداخل الحاويات الإضافية (راجِع تراكبات عناصر واجهة المستخدم باستخدام Grid لمزيد من التفاصيل).

enum class VideoPlayerArea { Player, Controller }

object PlayerGridConfig {
    // Default: Single area layout with overlay (controls on top of player)
    val defaultConfig: GridConfigurationScope.() -> Unit = {
        row(1f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1)
        area(areaId = VideoPlayerArea.Controller, row = 1, column = 1)
    }

    // Tabletop: Two rows splitting content across the fold
    val tabletopConfig: GridConfigurationScope.() -> Unit = {
        row(0.5f)
        row(0.5f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1) // Top half above fold
        area(areaId = VideoPlayerArea.Controller, row = 2, column = 1) // Bottom half below fold
    }
}

‫2. رصد وضع الشاشة المسطحة وتطبيق الإعدادات على الشبكة

استخدِم mediaQuery لاختيار الإعدادات النشطة استنادًا إلى windowPosture، ومرِّر config إلى Grid، واربط المحتوى البرمجي بمعرّفات المناطق. يضمن الإعلان عن VideoPlayerArea.Player قبل VideoPlayerArea.Controller أنه عندما تشترك كلتاهما في خلية في defaultConfig، يتم عرض عناصر التحكّم فوق المشغّل:

val config = mediaQuery {
    when (windowPosture) {
        Posture.Tabletop -> PlayerGridConfig.tabletopConfig
        else -> PlayerGridConfig.defaultConfig
    }
}

Grid(config = config) {
    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Player)
    ) {
        // VideoPlayerContent
    }

    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Controller)
    ) {
        // PlaybackControlsContent
    }
}

النتائج

من خلال الجمع بين mediaQuery وGrid، يرصد تطبيقك ديناميكيًا متى يتم طيّ جهاز قابل للطي جزئيًا في وضع "الكمبيوتر اللوحي"، ويعدِّل واجهة المستخدم تلقائيًا إلى منطقتَي عرض وظيفيتَين يفصل بينهما الطي.

مراجع إضافية