חדשות על מוצרים

מה חדש במהדורת אפריל 2026 של Jetpack Compose

משך הקריאה: 6 דקות
לצפייה בפרופיל של Meghan Mehta
Meghan Mehta נציג מפתחים, אנדרואיד

כיום, גרסת אפריל 2026 של Jetpack Compose יציבה. מהדורה זו מכילה גרסה 1.11 של מודולי Compose מרכזיים (ראו את מיפוי ה-BOM המלא), כלי ניפוי שגיאות משותפים באלמנטים, אירועי משטח עקיבה ועוד. יש לנו גם כמה ממשקי API ניסיוניים שנשמח אם תנסו אותם ותתנו לנו עליהם משוב.

כדי להשתמש בגרסה של היום, שדרגו את גרסת Compose BOM שלכם ל:

implementation(platform("androidx.compose:compose-bom:2026.04.01"))

שינויים בגרסה 1.11.0 של Compose

ביצוע קורוטין בבדיקות

אנו מציגים עדכון משמעותי באופן שבו Compose מטפל בתזמון הבחינות. בעקבות תקופת ההרשמה שהוכרזה ב-Compose 1.10, ממשקי ה-API לבדיקות גרסה 2 הם כעת ברירת המחדל, וממשקי ה-API לגרסה 1 הוצאו משימוש. השינוי המרכזי הוא שינוי במנהל הבדיקות המוגדר כברירת מחדל. בעוד שממשקי ה-API של גרסה 1 הסתמכו על ה-UnconfinedTestDispatcher, אשר ביצע קורוטינים באופן מיידי, ממשקי ה-API של v2 משתמשים ב-StandardTestDispatcher. משמעות הדבר היא שכאשר קורוטין מופעל בבדיקות שלך, הוא נמצא כעת בתור ואינו מבוצע עד שהשעון הווירטואלי מתקדם.

זה מחקה טוב יותר את תנאי הייצור, מסלק ביעילות את תנאי המרוץ והופך את חבילת הבדיקות שלך לחזקה ופחות רעועה משמעותית.

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

שיפורים משותפים של אלמנטים וכלי אנימציה

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

LookaheadAnimationVisualDebugging(
    overlayColor = Color(0x4AE91E63),
    isEnabled = true,
    multipleMatchesColor = Color.Green,
    isShowKeylabelEnabled = false,
    unmatchedElementColor = Color.Red,
) {
    SharedTransitionLayout {
        CompositionLocalProvider(
            LocalSharedTransitionScope provides this,
        ) {
            // your content
        }
    }
}

אירועים במשטח מגע

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

הוספנו גם תמיכה במחוות מורכבות יותר בלוח המגע, כפי שמזוהות על ידי הפלטפורמה החל מ-API 34, כולל החלקות עם שתי אצבעות וצביטות. רכיבים כמו Modifier.scrollable ו-Modifier.transformable מזהים אוטומטית את התנועות האלה כדי לשפר את ההתנהגות שלהם עם משטחי מגע.

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

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

beforeAndAfter.webp

ברירות מחדל של מארח ההרכבה (זמן ריצה של Compose)

הוספנו את HostDefaultProviderLocalHostDefaultProviderHostDefaultKey ו-ViewTreeHostDefaultKey כדי לספק שירותים ברמת המארח ישירות דרך compose-runtime. כך אין צורך בספריות להסתמך על compose-ui לחיפושים, ויש תמיכה טובה יותר ב-Kotlin Multiplatform. כדי לקשר את הערכים האלה לעץ הקומפוזיציה, יוצרי הספריות יכולים להשתמש ב-compositionLocalWithHostDefaultOf כדי ליצור CompositionLocal שמקבל ערכי ברירת מחדל מהמארח.

תצוגה מקדימה של עטיפות

תצוגות מקדימות בהתאמה אישית ב-Android Studio היא תכונה חדשה שמאפשרת להגדיר בדיוק איך התוכן של תצוגה מקדימה ב-Compose מוצג.

אם מטמיעים את הממשק PreviewWrapperProvider ומחילים את ההערה החדשה @PreviewWrapper, אפשר להוסיף בקלות לוגיקה מותאמת אישית, כמו החלה של Theme ספציפי. אפשר להחיל את ההערה על פונקציה עם ההערות @Composable ו-@Preview או @MultiPreview. כך מקבלים פתרון כללי וקל לשימוש שפועל בתכונות בגרסת טרום-השקה ומצמצם באופן משמעותי את הקוד שחוזר על עצמו.

class ThemeWrapper: PreviewWrapperProvider {
    @Composable
    override fun Wrap(content: @Composable (() -> Unit)) {
        JetsnackTheme {
            content()
        }
    }
}


@PreviewWrapper(ThemeWrapper::class)
@Preview
@Composable
private fun ButtonPreview() {
    // JetsnackTheme in effect
    Button(onClick = {}) {
        Text(text = "Demo")
    }
}

הוצאה משימוש והסרה

  • כפי שפורסם בפוסט בבלוג בנושא Compose 1.10, אנחנו מוציאים משימוש את Modifier.onFirstVisible(). השם שלו הוביל לעיתים קרובות לתפיסות מוטעות, במיוחד בפריסות עצלות, שבהן הוא הופעל מספר פעמים במהלך הגלילה. מומלץ לעבור אל Modifier.onVisibilityChanged(), שמאפשר מעקב ידני מדויק יותר אחרי מצבי החשיפה, בהתאם לדרישות הספציפיות של תרחיש השימוש שלכם.
  • הדגל ComposeFoundationFlags.isTextFieldDpadNavigationEnabled הוסר כי הניווט באמצעות מקשי החיצים ב-TextFields מופעל עכשיו תמיד כברירת מחדל. ההתנהגות החדשה מבטיחה שאירועים של כפתורי החיצים (D-pad) מלוח משחקים או משלט טלוויזיה יזיזו קודם את הסמן בכיוון הנתון. המיקוד יכול לעבור לרכיב אחר רק כשהסמן מגיע לסוף הטקסט.

ממשקי API עתידיים

בגרסה הקרובה של Compose‏ 1.12.0, ‏ compileSdk ישודרג ל-compileSdk 37, עם AGP 9 וכל האפליקציות והספריות שתלויות ב-Compose יירשו את הדרישה הזו. מומלץ להתעדכן בגרסאות האחרונות שפורסמו, כי המטרה של Compose היא לאמץ במהירות compileSdks חדשים כדי לספק גישה לתכונות האחרונות של Android. כדאי לעיין בתיעוד שזמין כאן כדי לקבל מידע נוסף על הגרסה של AGP שנתמכת ברמות שונות של API. 

ב-Compose 1.11.0, ממשקי ה-API הבאים מוצגים כ-@Experimental. נשמח לקבל מכם משוב אחרי שתנסו אותם באפליקציות שלכם. שימו לב: @Experimental APIs מסופקים לצורך הערכה וקבלת משוב בשלב מוקדם, ויכול להיות שיעברו שינויים משמעותיים או יוסרו בגרסאות עתידיות.

סגנונות (ניסיוני)

אנחנו משיקים API חדש וניסיוני של עיצוב. ‫Style API הוא פרדיגמה חדשה להתאמה אישית של רכיבים חזותיים של רכיבים, שבעבר בוצעה באמצעות משנים. הוא נועד לאפשר התאמה אישית מעמיקה ופשוטה יותר על ידי חשיפה של קבוצה סטנדרטית של מאפיינים שניתנים לעיצוב, עם עיצוב פשוט שמבוסס על מצב ומעברים מונפשים. ה-API החדש הזה כבר מניב שיפורים מבטיחים בביצועים. אנחנו מתכננים להשתמש בסגנונות ברכיבי Material אחרי ש-Style API יתייצב.

דוגמה בסיסית לשינוי הרקע של סגנון המצב של לחצן שנלחץ:

@Composable
fun LoginButton(modifier: Modifier = Modifier) {
    Button(
        onClick = {
            // Login logic
        },
        modifier = modifier,
        style = {
            background(
                Brush.linearGradient(
                    listOf(lightPurple, lightBlue)
                )
            )
            width(75.dp)
            height(50.dp)
            textAlign(TextAlign.Center)
            externalPadding(16.dp)

            pressed {
                background(
                    Brush.linearGradient(
                        listOf(Color.Magenta, Color.Red)
                    )
                )
            }
        }
    ){
        Text(
            text = "Login",
        )
    }
}
styles.webp

אפשר לעיין במסמכי התיעוד ולדווח על באגים כאן.

MediaQuery (ניסיוני)

ה-API החדש mediaQuery מספק דרך הצהרתית ויעילה להתאמת ממשק המשתמש לסביבה שלו. הוא מבצע הפשטה של אחזור מידע מורכב לתנאים פשוטים בתוך UiMediaScope, וכך מבטיח שקומפוזיציה מחדש תתבצע רק כשצריך.

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

@Composable
fun isTabletopPosture(
    context: Context = LocalContext.current
): Boolean {
    val windowLayoutInfo by
        WindowInfoTracker
            .getOrCreate(context)
            .windowLayoutInfo(context)
            .collectAsStateWithLifecycle(null)

    return windowLayoutInfo.displayFeatures.any { displayFeature ->
        displayFeature is FoldingFeature &&
            displayFeature.state == FoldingFeature.State.HALF_OPENED &&
            displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
    }
}

@Composable
fun VideoPlayer() {
    if(isTabletopPosture()) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

כעת, עם UIMediaQuery, ניתן להוסיף את התחביר של mediaQuery לשאילתת מאפייני מכשיר, כגון אם מכשיר נמצא במצב שולחן עבודה:

@OptIn(ExperimentalMediaQueryApi::class)
@Composable
fun VideoPlayer() {
    if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

עיין בתיעוד ודווח על כל באגים כאן.

רשת (ניסיונית)

Gridהוא ממשק API חדש וחזק לבניית פריסות דו-ממדיות מורכבות ב-Jetpack Compose. בעוד ש-Row ו-Column מצוינים לעיצובים ליניאריים, Grid מספק לכם את השליטה המבנית הדרושה לארכיטקטורה ברמת המסך ולרכיבים מורכבים ללא התקורה של רשימה ניתנת לגלילה. Grid מאפשר לך להגדיר את הפריסה שלך באמצעות מסלולים, פערים ותאים, ומציע אפשרויות גודל מוכרות כמו Dp, אחוזים, גדלי תוכן פנימיים ויחידות "Fr" גמישות. 

@OptIn(ExperimentalGridApi::class)
@Composable
fun GridExample() {
    Grid(
        config = {
            repeat(4) { column(0.25f) }
            repeat(2) { row(0.5f) }
            gap(16.dp)
        }
    ) {
        Card1(modifier = Modifier.gridItem(rowSpan = 2)
        Card2(modifier = Modifier.gridItem(colmnSpan = 3)
        Card3(modifier = Modifier.gridItem(columnSpan = 2)
        Card4()
    }
}

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

רשת.gif

עיין בתיעוד ודווח על כל באגים כאן

FlexBox (ניסיוני)

FlexBox הוא כלי פריסה שנועד לממשקי משתמש אדפטיביים בעלי ביצועים גבוהים. הוא מנהל את גודל הפריטים וחלוקת החלל בהתבסס על מידות המכולה הזמינות.הוא מטפל במשימות מורכבות כמו עיטוף (wrap) ויישור רב-צירי של פריטים (justifyContent, alignItems, alignContent). הוא מאפשר לפריטים לגדול (grow) או להתכווץ (shrink) כדי למלא את המיכל. 

@OptIn(ExperimentalFlexBoxApi::class)
fun FlexBoxWrapping(){
    FlexBox(
        config = {
            wrap(FlexWrap.Wrap)
            gap(8.dp)
        }
    ) {
        RedRoundedBox()
        BlueRoundedBox()
        GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
        OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
        PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
    }
}
AnimationGif.gif

עיין בתיעוד ודווח על כל באגים כאן.

הטמעה חדשה של SlotTable (ניסיונית)

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

כדי לנסות את החדשSlotTable, להפעילComposeRuntimeFlags.isLinkBufferComposerEnabled

התחילו לקודד עוד היום!

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

נכתב על ידי:
המשך קריאה