פריסת תנוחה על משטח עם Grid ו-mediaQuery

סמל של דירוג 4 כוכבים

במכשירים מתקפלים, כשמניחים אותם על משטח, המסך מתפצל לשני אזורים שמופרדים על ידי הקיפול הפיזי (או הציר). במצב שולחן, אפשר להציב את התוכן הראשי של האפליקציה (כמו נגן וידאו או משטח משחק) בחלק העליון, ואת הרכיבים האינטראקטיביים (כמו אמצעי בקרה של מדיה או לוחות בקרה) בחלק התחתון.

מכשיר מתקפל במצב שולחני שבו מוצג תוכן וידאו במסך העליון וכפתורי הפעלה במסך התחתון.
איור 1. במצב שולחן, התוכן ואמצעי הבקרה האינטראקטיביים מפוצלים לאורך הקיפול הפיזי.

שיטות מומלצות

כדי להוסיף תמיכה במצב שולחן לאפליקציה, משתמשים ב-API‏ Grid כדי להגדיר פריסה עם שתי שורות ועמודה אחת, ומחילים את שאילתת המדיה של מצב החלון 'שולחן'.

  • זיהוי תגובתי של תנוחת המכשיר על השולחן: אפשר להשתמש ברכיב הקומפוזבילי mediaQuery כדי לעקוב אחרי מצב המכשיר. כשמקפלים את המכשיר למצב שולחני (windowPosture == Posture.Tabletop), הפריסה משתנה באופן דינמי בלי שצריך להפעיל מחדש את הפעילות או לטפל במחזור החיים בצורה מורכבת.
  • שימוש ב-Grid כדי ליצור פריסות מובנות: כשמכשיר נמצא במצב שולחן, אפשר להשתמש ב-Grid API ‏ (2 rows, 1 column) כדי להפריד בצורה ברורה בין התוכן החזותי העיקרי בשורה העליונה מעל הקו הדמיוני, לבין אמצעי הבקרה האינטראקטיביים בשורה התחתונה מתחת לקו הדמיוני.
  • שימוש באינדקס Z מרומז לשכבות-על: בתנוחות רגילות (לא תנוחות של משחק על שולחן), מקצים כמה מזהי אזורים לאותה משבצת כדי להציג את אמצעי הבקרה כשכבת-על מעל השחקן. ‫Grid מעבדת באופן אוטומטי את הפריטים מהסוף להתחלה לפי סדר ההצהרה שלהם.
  • מעברים חלקים: חשוב לוודא שהמצב ומיקומי הגלילה נשמרים כשעוברים בין פריסות רגילות במסך מלא לבין מצב שולחן.

אלמנטים

  • ‫Grid: מאפשר למקם פריטים בשורות ובעמודות שניתנות להגדרה, ומתאים במיוחד לחלוקת תוכן בין אזורים שונים במסך.
  • ‫mediaQuery: ממשק API של Jetpack Compose שמשמש לשליחת שאילתה לגבי המיקום הנוכחי של חלון האפליקציה, גודל החלון ומאפייני החומרה ישירות בתוך רכיבי ה-Composable.

צעדים

שליחת שאילתה לגבי מצב האבטחה של המכשיר באמצעות mediaQuery(). כשהמכשיר מונח על השולחן, צריך לסדר את התוכן של האפליקציה ברשת אנכית עם שתי שורות ועמודה אחת, ולוודא שהתוכן העיקרי נשאר בחלק העליון והפקדים נשארים נגישים בחלק התחתון.

‫1. הגדרת תצורות של רשת המשבצות למצב שולחני

בתוך פונקציה שאפשר להרכיב, מגדירים מזהים של אזורי פריסה באמצעות enum ומגדירים בלוקים של GridConfigurationScope לתנוחות ברירת מחדל ולתנוחות של שולחן.

ב-defaultConfig, שני האזורים משויכים לאותה תא (row = 1, column = 1). ב-Grid נעשה שימוש באינדקס z משתמע, שבו רכיבי composable שמוצהרים מאוחר יותר בפריסה מעובדים מעל רכיבים קודמים, וכך אפשר להציג את שכבת הבקרה מעל הנגן בלי להוסיף קינון של רכיבי container (פרטים נוספים זמינים במאמר בנושא שכבות-על של רכיבי ממשק משתמש באמצעות 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, האפליקציה שלכם מזהה באופן דינמי מתי מכשיר מתקפל מקופל חלקית למצב 'על משטח, מסך למעלה', ומשנה אוטומטית את ממשק המשתמש לשני אזורי תצוגה פונקציונליים שמחולקים על ידי הקיפול.

מקורות מידע נוספים