היום, הגרסה של Jetpack פיתוח נייטיב מדצמבר 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, והוא נועד לצמצם באופן משמעותי את הבעיות שנובעות מעומסי עבודה כבדים בממשק המשתמש.
בעבר, אחרי שהתחלתם ליצור מוזיקה, הייתם צריכים לחכות עד שהיצירה תסתיים. אם הקומפוזיציה מורכבת, היא עלולה לחסום את ה-thread הראשי למשך זמן ארוך יותר מפריים אחד, ולגרום לממשק המשתמש לקפוא. עם ההרכבה שניתנת להשהיה, סביבת זמן הריצה יכולה עכשיו 'להשהות' את העבודה שלה אם היא מתקרבת לסיום הזמן, ולחדש את העבודה בפריים הבא. השיטה הזו יעילה במיוחד כשמשתמשים בה עם טעינה מראש של פריסת לייאאוט כדי להכין מסגרות מראש. ממשקי ה-API של פריסת Lazy CacheWindow שהוצגו ב-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. רכיב ה-MaterialTextתומך עכשיו בהתנהגות 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 וכלל הכתיבה שלכם משתפים את אותו מופע 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 מעיצובים.
- הבדיקות של איכות ממשק המשתמש בודקות את ממשק המשתמש שלכם כדי לזהות בעיות נפוצות, כמו בעיות נגישות, ומציעות פתרונות.
כדי לראות את הכלים האלה בפעולה, אפשר לצפות בהדגמה הזו:
כתיבה מהנה
אנחנו ממשיכים להשקיע ב-Jetpack פיתוח נייטיב כדי לספק לכם את ממשקי ה-API והכלים שאתם צריכים כדי ליצור ממשקי משתמש יפים ועשירים. המשוב שלכם חשוב לנו, ולכן נשמח אם תשתפו אותנו בדעתכם על השינויים האלה או תספרו לנו מה הייתם רוצים לראות בהמשך בכלי למעקב אחר בעיות.
להמשך הקריאה
-
חדשות על מוצרים
אם אתם מפתחי Android שרוצים להטמיע תכונות חדשניות מבוססות-AI באפליקציה שלכם, לאחרונה השקנו עדכונים חדשים ומתקדמים.
Thomas Ezan • משך הקריאה: 3 דקות
-
חדשות על מוצרים
Android 17 הגיע לגרסת בטא 4, גרסת הבטא המתוזמנת האחרונה של מחזור הפרסום הזה, אבן דרך קריטית לתאימות אפליקציות ויציבות הפלטפורמה.
Daniel Galpin • משך הקריאה: 4 דקות
-
חדשות על מוצרים
הפיכת Google Play לחוויה הכי בטוחה ומהימנה שאפשר. היום אנחנו מכריזים על סדרה חדשה של עדכוני מדיניות ועל תכונה להעברת חשבון, במטרה לשפר את פרטיות המשתמשים ולהגן על העסק שלכם מפני הונאות.
Bennet Manuel • משך הקריאה: 3 דקות
כדאי תמיד להיות בעניינים
רוצים לקבל טיפים עדכניים לפיתוח Android ישירות לאימייל כל שבוע?