היום, הגרסה של Jetpack Compose מאוגוסט 2026 יציבה! בגרסה הזו, גרסה 1.12 זמינה בכל מודולי הליבה של Compose (אפשר לעיין במיפוי המלא של BOM). נוספו ממשקי API ויזואליים עשירים כמו Mesh Gradients ותמיכה ב-Wide Color Gamut (WCG), תכונות פריסה מבניות כמו אזורים עם שמות ב-Grid, שילוב חלק עם Credential Manager של Android ושיפורים משמעותיים בבדיקות ובביצועים.
כדי לעדכן את הפרויקט שלך לגרסה של היום, שדרג את גרסת Compose BOM שלך ל-2026.08.00:
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
שינויים פורצי דרך
- AGP ו-Compile SDK: Compose 1.12 מעדכן את compileSdk ל-API 37, ולכן נדרשת גרסה מינימלית של AGP 9.1.2. תזכורת: תמיד מומלץ להשתמש ב-Compose עם הגרסה האחרונה של compileSdk. למידע נוסף על שינוי זה, כאן.
-
Modifier.onFirstVisible()הוצא משימוש: צריך לעבור אל Modifier.onVisibilityChanged(), שמאפשר מעקב מדויק יותר אחרי סף החשיפה.
גרפיקה
מעברי רשת
ב-Compose 1.12, הוספנו את MeshGradientPainter כדי לעזור לכם ליצור מעברי צבעים אורגניים עם כמה נקודות.
val rows = 1 val columns = 1 val gradientPainter = remember { MeshGradientPainter(rows, columns) { // Parameters: row, column, position, color setVertex(0, 0, Offset(0f, 0f), Color.Red) // Top-Left setVertex(0, 1, Offset(1f, 0f), Color.Blue) // Top-Right setVertex(1, 0, Offset(0f, 1f), Color.Green) // Bottom-Left setVertex(1, 1, Offset(1f, 1f), Color.Yellow) // Bottom-Right } } Box( modifier = modifier .aspectRatio(16/9f) .fillMaxWidth() .paint(gradientPainter) )
מידע נוסף ודוגמאות מופיעים במאמרי העזרה.
תמיכה בטווח צבעים רחב ו-HDR
צגים מודרניים מציעים נאמנות צבע מורחבת וטווח דינמי גבוה יותר. בגרסה Compose 1.12, תמיכה מלאה ב-Wide Color Gamut (P3) וב-Rendering HDR הופעלה בגרפיקה, צביעה ושיידרים של Compose. צבעים המוגדרים במרחבי צבע שאינם sRGB (כגון Display P3) נשמרים עד לעיבוד הפלטפורמה ללא הגבלת צבע. אם הצבעים משתמשים במרחב צבעים לא נתמך (למשל CieXyz, CieLab או Oklab), אם הם מסתמכים על מרחב צבעים בגרסה לא נתמכת של Android (למשל Bt2020Hlg ב-Android 13 ומטה) או אם האפליקציה פועלת ב-Android 9 (API 28) ומטה, הצבעים יחזרו בבטחה ל-sRGB.
שינויים בולטים אחרים:
LayerOutsetsנוסף לGraphicsLayerוModifier.graphicsLayer, שבאמצעותו ניתן להגדיל את הגבולות החזותיים של השכבה מעבר לגודלה הנמדד. כדי למנוע את ההתנהגות המרומזת שלclipToBoundsכשמקדמים את השכבה למאגר מחוץ למסך, צריך להחילLayerOutsets.
סגנונות
ב-Google I/O, שיתפנו את החזון המוקדם שלנו עבור Compose Styles API - דרך מאוחדת ויעילה לעיצוב רכיבים. מאז, המשכנו לבנות את הארכיטקטורה הבסיסית כדי להבטיח בטיחות טיפוס קפדנית ותקינות צפויה, ולתמוך בבניית מערכות עיצוב מותאמות אישית.
כדי להבטיח שנבצע את השכבה הבסיסית הזו בצורה נכונה, ממשק ה-API יישאר ניסיוני, וניתן לצפות לשינויים משמעותיים.
אופטימיזציות בזמן ריצה
מְקוּדָן תופעת לוואי לְהַעֲמִיס יוֹתֵר מִדַי
SideEffectכעת תומך בארגומנטים של מפתח, המאפשרים לך להפעיל אפקטים לוואי חד פעמיים בכל פעם שמפתחות ספציפיים משתנים. זה יכול להוביל לביצועים טובים יותר בהשוואה לשימוש ב-LaunchedEffect או DisposableEffect כאשר אינך זקוק לקורוטין או לבלוק הדיספוקס.SideEffect מהיר יותר בעד 90% מ-LaunchedEffect ובכ-20% מ-DisposableEffect. שימו לב ש-SideEffect פועל לפני DisposableEffect ו-LaunchedEffect, לכן צריך להיזהר אם מעבירים אפקטים קיימים ל-API הזה, במיוחד אם מדובר ב-LaunchedEffects שמסתמך על שליחה כדי להתחיל אחרי שהפריים הנוכחי מסתיים.
@Composable fun AnalyticsTracker(userId: String, screenName: String) { SideEffect(key1 = userId, key2 = screenName) { analytics.logScreenView(userId, screenName) } }
אנימציה
DeferredTargetAnimationסיים את הסטטוס הניסיוני.
מעברים אינטראקטיביים בשני שלבים
- קומפוזיבלים חדשים:
DeferredAnimatedContentוDeferredAnimatedVisibilityמאפשרים יצירת מעברים דו-שלביים מקסימים, למשל למעקב חזוי אחר מחוות חזרה. - שליטה ידנית באנימציה: במהלך השלב הדחוי של מעבר, אפשר עכשיו לתפעל באופן ידני בזמן אמת מאפיינים של אנימציה (כמו קנה מידה או היסט) (לדוגמה, מעקב אחרי תנועת החלקה).
- מסירה חלקה: לאחר סיום השלב הנדחה, מנוע המעבר משתלט ומבצע מסירה חלקה, כולל העברת מהירות, למעבר האוטומטי.
- תמיכה באלמנטים משותפים חדש
permitTransformDuringDeferredTransitionדגל בSharedContentConfigשולט אם אלמנטים משותפים עוברים טרנספורמציה ויזואלית יחד עם המכולות של האב שלהם במהלך שלב המעבר הנדחה.
val state = remember { DeferredTransitionState(initialScreen) } val transition = rememberDeferredTransition(state) if (predictiveBackInProgress) { state.defer(targetScreen) } else { state.animateTo(targetScreen) } transition.DeferredAnimatedContent( targetState = targetScreen, mutableTransformSpec = { MutableContentTransform { // Manually manipulate properties during the deferred phase initialContentTransform { scale = swipeProgress } } } ) { screen -> ScreenContent(screen) }
להלן שתי הדגמות של מקרי שימוש בהם אנימציה מונעת מחוות מועברת לאנימציה מופעלת:
שילובים של טקסט, קלט ופלטפורמות
עיצוב טקסט שניתן לערוך
ממשקי API חדשים מציעים עיצוב טקסט עשיר לטקסט שניתן לעריכה ב-BasicTextField. עכשיו אפשר להחיל ולשנות עיצוב של תווים ופסקאות בתוך השורה באופן פרוגרמטי באמצעות SpanStyle ו-ParagraphStyle דרך המתודה החדשה addStyle() בתוך היקף TextFieldBuffer (למשל בתוך textFieldState.edit { ... } או InputTransformation). בנוסף, TextFieldBuffer מספקת ממשקי API של getSpanStyles() ו-getParagraphStyles() שמחזירים אובייקטים של TrackedRange, וכך מאפשרים לקרוא, לעדכן או להסיר סגנונות שהוחלו. כדי להשלים את יצירת העיצוב, TextFieldState חושף כעת מאפיין textStyles לקריאה בלבד לשאילתות סגנונות פעילים בטווחים שונים, בעוד ש-TextFieldBuffer מספק את originalTextStyles לבדיקת מצב העיצוב לפני עריכה. עיצוב הטקסט וההערות המותאמות אישית נשמרים גם אחרי שינויים בהגדרות.
val state = rememberTextFieldState("Formatted text in Compose 1.12") // Apply bold and color styles to a range of text state.edit { addStyle( SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue), start = 0, end = 9 ) } // Query active styles from TextFieldState val currentStyles = state.textStyles
בחירת טקסט
חדשSelectionState API מספק שליטה תכנותית ויכולת צפייה על בחירת טקסט בתוךSelectionContainer. הרמת אובייקט של SelectionState דרך rememberSelectionState() ומעבר לתוך SelectionContainer חושפת את selectedTexts כרשימה ריאקטיבית של AnnotatedStrings ומספקת שיטות כמו selectAll(), clear(), select(TextRange) ו-extendSelectionByWord().
בנוסף, אפשר להשתמש ב-getSelectableTexts() כדי לאחזר את כל פריטי הטקסט שאפשר לבחור לפי סדר הפריסה, ולבחור טקסט ברכיבים הניתנים להרכבה ב-SelectionContainer באמצעות טווח גלובלי.
@Composable fun ProgrammaticSelectionExample() { val selectionState = rememberSelectionState() Column { Button( onClick = { selectionState.selectAll() }, modifier = Modifier.disableSelectionClearOnTap() ) { Text("Select All") } SelectionContainer(state = selectionState) { Text("Text content to be selected programmatically.") } } }
Credential Manager Integration
שדות הטקסט של Compose משולבים עכשיו באופן מקורי עם Credential Manager ב-Android (API 34 ומעלה) באמצעות מסגרת מילוי אוטומטי (מתחת ל-API 34, הטיפול מתבצע על ידי androidx.credentials library). על ידי צירוף מאפיין ה-semantics החדש credentialRequest עם CredentialRequestData, קלט הטקסט יכול להציג בקשות למפתחות גישה, לפרטי כניסה שמורים או לכניסה ישירות בתהליך קלט של משתמשים.
@Composable fun LoginField(textFieldState: TextFieldState) { val credentialData = remember { CredentialRequestData( // Specify Credential Manager request options ) } BasicTextField( state = textFieldState, modifier = Modifier.semantics { credentialRequest = credentialData } ) }
שינויים בולטים אחרים:
- תמיכה בהגדרות וריאציות גופנים בגופנים להורדה.
- גלילה אוטומטית מופעלת בעת גרירת בחירת טקסט מעבר לחלון התצוגה ב
SelectionContainer. - נוספה תמיכה בצלילי אינטראקציה אוטומטיים (קליקים וניווט במיקוד) לרכיבי Compose, עם קומפוזיציה חדשה
SoundEffectOnInteractionשמאפשרת ביטול הסכמה. שימו לב: כתוצאה מהשינוי הזה, עכשיו צריך להפעיל את מאזיני הקליקים הסמנטיים מה-thread הראשי, וזה עשוי להשפיע על מספר קטן של תרחישי בדיקה. -
KeyboardTypeכולל עכשיו אתDate,Time,DateTimeו-SignedDecimal. BasicSecureTextFieldמשתמש כעתTextObfuscationMode.Systemכברירת מחדל, בעודRevealLastTypedמשמש כעקיפה מוחלטת.
שיפורי פריסה
אזורים בעלי שם בפריסת רשת
בניית פריסות דו-ממדיות מורכבות קלה יותר כעת עם אזורים בעלי שם ברכיב @Experimental Grid. במקום לנהל אינדקסים מספריים של עמודות ושורות בפריטים שונים, ניתן להגדיר אזורים סמנטיים ב-GridConfigurationScope ולמקם פריטים הניתנים להרכבה לפי שם אזור.
@OptIn(ExperimentalGridApi::class) @Composable fun DashboardLayout() { Grid( config = { area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2) area("sidebar", row = 1, column = 0) area("content", row = 1, column = 1) gap(16.dp) } ) { HeaderSection(modifier = Modifier.gridItem(areaId = "header")) NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar")) MainContentView(modifier = Modifier.gridItem(areaId = "content")) } }
למידע נוסף, עיין בתיעוד.
ביצועים
כמו בכל גרסה, אנחנו ממשיכים להשקיע בביצועים של Compose כדי לוודא שהמסגרת עוזרת לכם ליצור אפליקציות יפות ויעילות. בגרסה הזו התמקדנו בשיפור הביצועים של ההפעלה, ועכשיו אנחנו רואים זמן עד להצגה הראשונית (הזמן שנדרש לאפליקציה כדי ליצור את הפריימים הראשונים) שדומה לנתוני הצפיות במדדי ההשוואה שלנו.
בדיקות ושדרוגי כלים
סינכרון בדיקה
גרסה 1.12 של Compose מציגה ממשקי API חדשים לבדיקות שנועדו להפחית את זמני ביצוע הבדיקות ולחסל אי יציבות במהלך דגימת מצבים:
-
hasPendingWork: בודקת באופן פסיבי אם יש עבודה בהמתנה בממשק המשתמש בלי להריץ את השעון, וזה אידיאלי ללולאות אנימציה ידניות. -
runWithoutImplicitWait: השבתה זמנית של סנכרון מרומז כשמבצעים מעבר בין מסגרות זמן ידניות (למשל, בדיקות אנימציה).
@Test fun testAnimationStateFast() { composeTestRule.mainClock.autoAdvance = false while (composeTestRule.hasPendingWork()) { composeTestRule.mainClock.advanceTimeByFrame() composeTestRule.waitForIdle() composeTestRule.runOnUiThread { composeTestRule.runWithoutImplicitWait { // This is most effective when querying multiple nodes in a single frame. // It prevents the redundant synchronization overhead that would // otherwise occur on every individual query. val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode() val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode() assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left) } } } }
שינויים בולטים אחרים:
- ה-API
captureToImageמאפשר עכשיו לצלם חלון קופץ או תיבת דו-שיח יחד עם רכיב העוגן שלהם במפת סיביות אחת. - נוספה
onRootWithViewInteractionכדי להגדיר את היקף החיפושים הסמנטיים של Compose לתצוגות ספציפיות של Android. כך אפשר לפשט את הבדיקה של ממשקי משתמש היברידיים, כמוRecyclerViews, בלי שיהיה צורך בתגי בדיקה ייחודיים בקוד הפקה. @PreviewWrapperכעת ניתן להחיל הערות על יישומים מותאמים אישית@MultiPreviewמחלקות, המאפשרות הגדרות תצוגה מקדימה לשימוש חוזר (כגון ערכות נושא מותאמות אישית) על פני רכיבים מרובים.
כתיבה מהנה!
Compose 1.12 הופך את פיתוח האפליקציות לקל ובעל ביטוי רב יותר מאי פעם, עם מעברי צבע של רשת, תמיכה בסולם צבעים רחב, גופנים משתנים להורדה, שילוב עם Credential Manager וכלי בדיקה מהירים יותר. כרגיל, אנו מעריכים את דעתכם, לכן אנא שתפו את המשוב שלכם על השינויים הללו או על מה שתרצו לראות בהמשך במעקב הבעיות שלנו. כתיבה מהנה!
-
חדשות על מוצריםעם ההשקה של Pixel 11 Pro Fold, Pixel Watch 5 וכל משפחת Pixel, המשתמשים יכולים לעבור בצורה חלקה בין גדלי מסך שונים, תנוחות ייחודיות וחוויות חכמות.
-
חדשות על מוצריםהיום אנחנו מציינים באופן רשמי חמש שנים מאז ההשקה של Jetpack Compose 1.0. מאז גרסה 1.0, שהשקתה הוכרזה ב-28 ביולי 2021, ועד לגרסה 1.11 האחרונה, ראינו את ממשקי ה-API מתפתחים באופן משמעותי במהלך השנים, ואנחנו רוצים לעצור לרגע ולחגוג את זה.
Rebecca Franks, Nick Butcher, Loryn Hairston • משך הקריאה: 4 דקות -
חדשות על מוצריםבמהלך כמעט 5 השנים שחלפו מאז השקת Jetpack Compose, השקענו מאמצים כדי לספק לכם את כל התכונות, הביצועים והכלים שאתם צריכים כדי ליצור ממשקי משתמש מדהימים במגוון מכשירי Android.
Nick Butcher • משך הקריאה: 2 דקות
רוצים לקבל טיפים עדכניים לפיתוח Android ישירות לאימייל כל שבוע?