היום, הגרסה של Jetpack Compose מדצמבר 2025 יציבה. הגרסה הזו כוללת את גרסה 1.10 של מודולי הליבה של Compose ואת גרסה 1.4 של Material 3 (אפשר לעיין במיפוי המלא של BOM), ונוספו בה תכונות חדשות ושיפורים משמעותיים בביצועים.
כדי להשתמש בגרסה של היום, צריך לשדרג את גרסת ה-BOM של Compose ל-2025.12.00:
implementation(platform("androidx.compose:compose-bom:2025.12.00"))שיפורים בביצועים
אנחנו יודעים שביצועי זמן הריצה של האפליקציה חשובים מאוד לך ולמשתמשים שלך, ולכן הביצועים היו בראש סדר העדיפויות של צוות Compose. הגרסה הזו כוללת מספר שיפורים – וכל מה שצריך לעשות כדי ליהנות מהם הוא לשדרג לגרסה העדכנית. השוואות הביצועים הפנימיות שלנו מראות שהביצועים של Compose זהים לביצועים שהיו מתקבלים אם הייתם משתמשים ב-Views:
השוואה בין Views לבין Jetpack Compose בגרסאות שונות של Compose, לצורך השוואה בין ביצועי הגלילה
השהיית קומפוזיציה בטעינה מראש עצלה
האפשרות להשהות את ההרכבה בשליפה מראש עצלה מופעלת עכשיו כברירת מחדל. זהו שינוי מהותי באופן שבו פועלים תזמונים של זמן ריצה של Compose, והוא נועד לצמצם באופן משמעותי את הבעיות שנוצרות במהלך עומסי עבודה כבדים של ממשק המשתמש.
בעבר, אחרי שהתחלתם ליצור מוזיקה, הייתם צריכים לחכות עד שהיצירה תסתיים. אם הקומפוזיציה מורכבת, היא עלולה לחסום את ה-thread הראשי למשך זמן ארוך יותר מפריים אחד, ולגרום לממשק המשתמש לקפוא. עם האפשרות להשהות את ההרכבה, זמן הריצה יכול עכשיו 'להשהות' את העבודה אם נגמר לו הזמן, ולחדש את העבודה בפריים הבא. השיטה הזו יעילה במיוחד כשמשתמשים בה עם טעינה מראש של פריסות עצלות כדי להכין מסגרות מראש. ממשקי ה-API של CacheWindow בפריסת Lazy, שהוצגו ב-Compose 1.9, הם דרך מצוינת לאחזור מראש של תוכן נוסף וליהנות מהשהיה של הקומפוזיציה כדי לשפר את הביצועים של ממשק המשתמש.
קומפוזיציה ניתנת להשהיה בשילוב עם שליפה מראש עצלנית עוזרות לצמצם בעיות בממשק
בנוסף, שיפרנו את הביצועים במקומות אחרים, כולל Modifier.onPlaced, Modifier.onVisibilityChanged ויישומים אחרים של משנים. נמשיך להשקיע בשיפור הביצועים של התכונה 'כתיבה בעזרת AI'.
תכונות חדשות
שימור
ל-Compose יש מספר ממשקי API לשמירה ולניהול של מצב במחזורי חיים שונים. לדוגמה, remember שומר את המצב בין קומפוזיציות, ו-rememberSavable/rememberSerializable שומר את המצב בין פעילויות או בין יצירות מחדש של תהליכים. retain הוא API חדש שפועל בין ממשקי ה-API האלה, ומאפשר לכם לשמור ערכים אחרי שינויים בהגדרות בלי שהם יעברו סריאליזציה, אבל לא אחרי סיום התהליך. retain לא מבצע סריאליזציה של המצב, ולכן אפשר לשמור אובייקטים כמו ביטויי למדה, זרימות ואובייקטים גדולים כמו מפות סיביות, שלא ניתן לבצע להם סריאליזציה בקלות. לדוגמה, אפשר להשתמש ב- retain כדי לנהל נגן מדיה (כמו ExoPlayer) ולוודא שהפעלת המדיה לא מופרעת בגלל שינוי בהגדרה.
@Composable
fun MediaPlayer() {
val applicationContext = LocalContext.current.applicationContext
val exoPlayer = retain { ExoPlayer.Builder(applicationContext).apply { ... }.build() }
...
}אנחנו רוצים להודות לקהילת AndroidDev (במיוחד לצוות Circuit), שהשפיעה על העיצוב של התכונה הזו ותמכה בו.
חומר 1.4
בגרסה 1.4.0 של ספריית material3 נוספו מספר רכיבים חדשים ושיפורים:
-
TextFieldמציע עכשיו גרסה ניסיונית שמבוססת עלTextFieldState, ומספקת שיטה יציבה יותר לניהול מצב הטקסט. בנוסף, יש עכשיו וריאציות חדשות שלSecureTextFieldושלOutlinedSecureTextField. רכיב ה-MaterialTextcomposable תומך עכשיו בהתנהגות autoSize. - רכיב הקרוסלה מציע עכשיו
HorizontalCenteredHeroCarouselוריאציה חדשה. - עכשיו אפשר לעבור בין מצב הבחירה למצב ההזנה ב-
TimePicker. - נקודת אחיזה אנכית לגרירה עוזרת למשתמשים לשנות את הגודל או המיקום של חלונית דינמית.
קרוסלת תמונות מרכזית אופקית
הערה: ממשקי ה-API של Material 3 Expressive ממשיכים להתפתח בגרסאות האלפא של ספריית material3. מידע נוסף זמין בהרצאה הבאה:
תכונות חדשות שקשורות לאנימציות
אנחנו ממשיכים להרחיב את ממשקי ה-API של האנימציות שלנו, כולל עדכונים להתאמה אישית של אנימציות של רכיבים משותפים.
אלמנטים דינמיים משותפים
כברירת מחדל, האנימציות של sharedElement() ושל sharedBounds() מנסות להנפיש
שינויים בפריסה בכל פעם שנמצא מפתח תואם במצב היעד. עם זאת, יכול להיות שתרצו להשבית את האנימציה הזו באופן דינמי על סמך תנאים מסוימים, כמו כיוון הניווט או המצב הנוכחי של ממשק המשתמש.
כדי לקבוע אם מעבר הרכיב המשותף יתרחש, אפשר עכשיו להתאים אישית את SharedContentConfig שמועבר אל rememberSharedContentState(). המאפיין isEnabled קובע אם הרכיב המשותף פעיל.
SharedTransitionLayout {
val transition = updateTransition(currentState)
transition.AnimatedContent { targetState ->
// Create the configuration that depends on state changing.
fun animationConfig() : SharedTransitionScope.SharedContentConfig {
return object : SharedTransitionScope.SharedContentConfig {
override val SharedTransitionScope.SharedContentState.isEnabled: Boolean
get() =
// determine whether to perform a shared element transition
}
}
}מידע נוסף זמין במאמרי העזרה.
Modifier.skipToLookaheadPosition()
בגרסה הזו נוסף משנה חדש, Modifier.skipToLookaheadPosition(), ששומר על המיקום הסופי של רכיב שאפשר להרכיב כשמבצעים אנימציות של רכיבים משותפים. כך אפשר לבצע מעברים כמו אנימציה מסוג 'חשיפה', כפי שאפשר לראות בדוגמה של Androidify עם החשיפה ההדרגתית של המצלמה. מידע נוסף זמין בסרטון הבא:
מהירות התחלתית במעברים של רכיבים משותפים
בגרסה הזו הוספנו API חדש למעבר בין רכיבים משותפים, prepareTransitionWithInitialVelocity, שמאפשר להעביר מהירות התחלתית (למשל ממחוות) למעבר בין רכיבים משותפים:
Modifier.fillMaxSize()
.draggable2D(
rememberDraggable2DState { offset += it },
onDragStopped = { velocity ->
// Set up the initial velocity for the upcoming shared element
// transition.
sharedContentStateForDraggableCat
?.prepareTransitionWithInitialVelocity(velocity)
showDetails = false
},
)
אנימציה של מעבר בין רכיבים משותפים שמתחילה במהירות התחלתית ממחוות
מעברים מוסתרים
הפונקציות EnterTransition ו-ExitTransition מגדירות איך רכיב ה-AnimatedVisibility/AnimatedContent יופיע או ייעלם. אפשרות ניסיונית חדשה של מסך מאפשרת לכם לציין צבע למסך או לתוכן; לדוגמה, הוספה והסרה של שכבה שחורה חצי אטומה מעל התוכן:
תוכן אנימציה מוסתר – שימו לב לווילון (או למסך) החצי אטום מעל תוכן הרשת במהלך האנימציה
AnimatedContent(
targetState = page,
modifier = Modifier.fillMaxSize().weight(1f),
transitionSpec = {
if (targetState > initialState) {
(slideInHorizontally { it } togetherWith
slideOutHorizontally { -it / 2 } + veilOut(targetColor = veilColor))
} else {
slideInHorizontally { -it / 2 } +
unveilIn(initialColor = veilColor) togetherWith slideOutHorizontally { it }
}
},
) { targetPage ->
...
}
השינויים הקרובים
הוצאה משימוש של Modifier.onFirstVisible
ב-Compose 1.9 הושקו Modifier.onVisibilityChanged ו-Modifier.onFirstVisible. בדקנו את המשוב שלך והבנו שלא ניתן לכבד את החוזה של Modifier.onFirstVisible באופן דטרמיניסטי, במיוחד כשפריט first הופך לגלוי. לדוגמה, פריסה מסוג Lazy עשויה להסיר פריטים שיוצאים מהתצוגה, ואז להוסיף אותם מחדש אם הם חוזרים לתצוגה. במקרה כזה, ההתקשרות חזרה onFirstVisible תופעל שוב, כי מדובר בפריט חדש. התנהגות דומה תתרחש גם כשחוזרים למסך שביקרתם בו קודם ומכיל onFirstVisible. לכן החלטנו להוציא משימוש את שינוי ההתנהגות הזה בגרסה הבאה של Compose (1.11) ואנחנו ממליצים לעבור אל onVisibilityChanged. מידע נוסף זמין במאמרי העזרה.
העברת שגרות המשך (coroutine) בבדיקות
אנחנו מתכננים לשנות את השליחה של שגרות המשך (coroutine) בבדיקות כדי לשפר את היציבות של הבדיקות ולזהות יותר בעיות. בשלב הזה, הבדיקות משתמשות ב-UnconfinedTestDispatcher, ששונה מההתנהגות בסביבת הייצור. לדוגמה, יכול להיות שאפקטים יופעלו באופן מיידי במקום להתווסף לתור. בגרסה עתידית, אנחנו מתכננים להשיק API חדש שמשתמש ב- StandardTestDispatcher כברירת מחדל כדי להתאים להתנהגויות בסביבת הייצור. אתם יכולים לנסות את ההתנהגות החדשה עכשיו בגרסה 1.10:
@get:Rule // also createAndroidComposeRule, createEmptyComposeRule val rule = createComposeRule(effectContext = StandardTestDispatcher())
השימוש ב-StandardTestDispatcher יוסיף משימות לתור, ולכן צריך להשתמש במנגנוני סנכרון כמו composeTestRule.waitForIdle() או composeTestRule.runOnIdle(). אם הבדיקה שלכם משתמשת ב-runTest, אתם צריכים לוודא ש-runTest והכלל Compose שלכם משתפים את אותו מופע של StandardTestDispatcher לצורך סנכרון.
// 1. Create a SINGLE dispatcher instance
val testDispatcher = StandardTestDispatcher()
// 2. Pass it to your Compose rule
@get:Rule
val composeRule = createComposeRule(effectContext = testDispatcher)
@Test
// 3. Pass the *SAME INSTANCE* to runTest
fun myTest() = runTest(testDispatcher) {
composeRule.setContent { /* ... */ }
}
כלים
ממשקי API מעולים ראויים לכלים מעולים, וב-Android Studio יש כמה תוספות חדשות למפתחי Compose:
- שינוי ממשק המשתמש: כדי לשפר את העיצובים, לוחצים לחיצה ימנית על
@Preview, בוחרים באפשרות 'שינוי ממשק המשתמש' ואז מתארים את השינוי בשפה טבעית. - יצירה
@Preview: לוחצים לחיצה ימנית על רכיב שאפשר להרכיב ובוחרים באפשרות Gemini > יצירת תצוגה מקדימה של [שם הרכיב] . - התאמה אישית של סמלי Material עם תמיכה חדשה בווריאציות של סמלים באשף Vector Asset.
- ליצור קוד מצילום מסך או לבקש מ-Gemini להתאים את ממשק המשתמש הקיים לתמונת יעד. אפשר לשלב את התכונה הזו עם תמיכה מרחוק ב-MCP, למשל כדי להתחבר לקובץ Figma וליצור ממשק משתמש של Compose מעיצובים.
- הבדיקות של Fix UI quality issues בודקות את ממשק המשתמש שלכם כדי לזהות בעיות נפוצות, כמו בעיות נגישות, ומציעות פתרונות.
כדי לראות את הכלים האלה בפעולה, אפשר לצפות בהדגמה הזו:
כתיבה מהנה
אנחנו ממשיכים להשקיע ב-Jetpack Compose כדי לספק לכם את ממשקי ה-API והכלים שדרושים ליצירת ממשקי משתמש יפים ועשירים. המשוב שלכם חשוב לנו, ולכן נשמח אם תשתפו אותנו בדעתכם על השינויים האלה או על מה שהייתם רוצים לראות בהמשך בכלי למעקב אחר בעיות.
להמשך הקריאה
-
חדשות על מוצרים
במהלך כמעט 5 השנים שחלפו מאז השקת Jetpack Compose, השקענו במתן כל התכונות, הביצועים והכלים שאתם צריכים כדי ליצור ממשקי משתמש מדהימים במגוון מכשירי Android.
Nick Butcher • משך הקריאה: 2 דקות
-
חדשות על מוצרים
אנחנו ב-Google Play מחויבים לספק למשתמשים את החוויה הכי טובה שאפשר, ולוודא שלמפתחים יש את הכלים והגמישות הדרושים כדי להצליח.
Paul Feng • משך הקריאה: 3 דקות
-
חדשות על מוצרים
בשנה שעברה השקנו אימות מפתחים ב-Android כדי לחזק את אבטחת הסביבה העסקית ולמנוע מגורמים זדוניים להסתתר מאחורי אנונימיות כדי לפרסם אפליקציות מזיקות.
Matthew Forsythe • משך הקריאה: 2 דקות
כדאי תמיד להיות בעניינים
רוצים לקבל טיפים עדכניים לפיתוח Android ישירות לאימייל כל שבוע?