הפעלת מודעות לקיפול באפליקציה

מסכים גדולים במצב פתוח ומצבים ייחודיים במצב מקופל מאפשרים ליצור חוויות משתמש חדשות במכשירים מתקפלים. כדי שהאפליקציה תתאים למכשירים מתקפלים ב-Jetpack Compose, צריך להשתמש בספריית Compose Material 3 Adaptive, שמספקת ממשקי API לתכונות של חלונות במכשירים מתקפלים, כמו קיפולים, צירים ומצבי מכשיר. אם האפליקציה מודעת לקיפול, היא יכולה להתאים את הפריסה שלה כדי להימנע ממיקום תוכן חשוב באזור הקיפולים או הצירים, ולהשתמש בקיפולים ובצירים כמפרידים טבעיים.

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

מידע על החלון

ב-Jetpack Compose, משתמשים בפונקציה הניתנת להרכבה collectFoldingFeaturesAsState() כדי לצפות במידע על קיפול החלון. ‫collectFoldingFeaturesAsState() אוסף את התכונות הנוכחיות של קיפול החלון מ-WindowInfoTracker לתוך State של Compose שמכיל רשימה של אובייקטים מסוג FoldingFeature.

מכיוון שהפונקציה collectFoldingFeaturesAsState() מחזירה את הפונקציה Compose State, הרכיבים הניתנים להרכבה מחדש מורכבים מחדש באופן אוטומטי בכל פעם שמצב הקיפול או המיקום של המכשיר משתנים, בלי שנדרש ניהול ידני של מחזור החיים או איסוף של זרימת נתונים:

@Composable
fun FoldAwareScreen() {
    val foldingFeatures by collectFoldingFeaturesAsState()

    // Access folding features for the current window.
    val foldFeature = foldingFeatures.firstOrNull()
    if (foldFeature != null) {
        // Adapt layout based on the fold feature.
    }
}

תכונות של מסכים מתקפלים

רשימת הרכיבים FoldingFeature שמוחזרים על ידי collectFoldingFeaturesAsState() (סוג משנה של DisplayFeature) מספקת מידע על מסכים מתקפלים, כולל המאפיינים הבאים:

  • state: מצב הקיפול של המכשיר, FLAT או HALF_OPENED

  • orientation: הכיוון של הקיפול או הציר, HORIZONTAL או VERTICAL

  • occlusionType: האם הקיפול או הציר מסתירים חלק מהמסך, NONE או FULL

  • isSeparating: האם הקיפול או הציר יוצרים שני אזורי תצוגה לוגיים, true או false

מכשיר מתקפל שHALF_OPENED תמיד מדווח על isSeparating כערך true כי המסך מחולק לשני אזורי תצוגה. בנוסף, הערך של isSeparating הוא תמיד True במכשיר עם שני מסכים כשהאפליקציה משתרעת על שני המסכים.

המאפיין FoldingFeature bounds (שעובר בירושה מ-DisplayFeature) מייצג את המלבן התוחם של תכונת קיפול, כמו קיפול או ציר. אפשר להשתמש בגבולות כדי למקם רכיבים במסך ביחס לתכונה:

@Composable
fun FoldFeatureDemo() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    if (foldFeature != null) {
        val isSeparating = foldFeature.isSeparating
        val occlusionType = foldFeature.occlusionType
        val bounds = foldFeature.bounds
        // Use bounds and properties to position content.
    }
}

מצב שולחני

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

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

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

כדי לקבוע אם המכשיר נמצא במצב שולחן, משתמשים ב-FoldingFeature.State וב-FoldingFeature.Orientation מ-collectFoldingFeaturesAsState():

@Composable
fun TabletopContent() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    val isTableTopPosture = foldFeature != null &&
        foldFeature.state == FoldingFeature.State.HALF_OPENED &&
        foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL

    if (isTableTopPosture) {
        // Tabletop layout: separate content and controls across the fold.
    } else {
        // Standard layout.
    }
}

אפשרות אחרת היא לבדוק את המאפיין Posture שמוחזר על ידי currentWindowAdaptiveInfoV2() כדי לקבוע אם החלון נמצא במצב שולחן:

val adaptiveInfo = currentWindowAdaptiveInfoV2()
val isTabletop = adaptiveInfo.windowPosture.isTabletop

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

דוגמאות

מצב הספר

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

אפשר להשתמש בו גם לצילום אם רוצים לצלם תמונות ללא מגע יד ביחס גובה-רוחב שונה.

מטמיעים את מצב הספר באותן טכניקות שבהן משתמשים למצב שולחן. בודקים שהכיוון של תכונת הקיפול הוא אנכי ולא אופקי:

@Composable
fun BookContent() {
    val foldingFeatures by collectFoldingFeaturesAsState()
    val foldFeature = foldingFeatures.firstOrNull()

    val isBookPosture = foldFeature != null &&
        foldFeature.state == FoldingFeature.State.HALF_OPENED &&
        foldFeature.orientation == FoldingFeature.Orientation.VERTICAL

    if (isBookPosture) {
        // Book posture layout: two-page layout across the vertical fold.
    } else {
        // Standard single-page layout.
    }
}

שינויים בגודל החלון

אזור התצוגה של אפליקציה יכול להשתנות כתוצאה משינוי בהגדרת המכשיר. לדוגמה, כשהמכשיר מקופל או נפתח, מסובב או משנה את הגודל במצב ריבוי חלונות.

כדי לאחזר את סיווג הגודל הנוכחי של החלון ולהתאים לשינויים בגודל ב-Jetpack Compose, משתמשים בפונקציה הקומפוזבילית currentWindowAdaptiveInfoV2() מתוך ספריית Compose Material 3 Adaptive. ‫currentWindowAdaptiveInfoV2() מחזירה מופע WindowAdaptiveInfo שמספק את WindowSizeClass של החלון הנוכחי (עם תמיכה בנקודות עצירה גדולות וגדולות במיוחד כברירת מחדל), וגם את windowPosture של המכשיר:

@Composable
fun AdaptiveApp() {
    val adaptiveInfo = currentWindowAdaptiveInfoV2()
    val windowSizeClass = adaptiveInfo.windowSizeClass

    when {
        windowSizeClass.isWidthAtLeastBreakpoint(
            WIDTH_DP_EXPANDED_LOWER_BOUND
        ) -> {
            // Expanded layout
        }
        windowSizeClass.isWidthAtLeastBreakpoint(
            WIDTH_DP_MEDIUM_LOWER_BOUND
        ) -> {
            // Medium layout
        }
        else -> {
            // Compact layout
        }
    }
}

איך משתמשים בסיווגים של גודל החלון

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

מידע נוסף על פריסות שמותאמות למכשירים מתקפלים ועל מכשירים מתקפלים זמין במקורות המידע הבאים:

דוגמאות

Codelabs