מעבר מ-Material 2.5 ל-Material 3 ב-Compose ל-Wear OS

‫Material 3 Expressive הוא השלב הבא בהתפתחות של Material Design. הוא כולל עדכונים של ערכות נושא, רכיבים ותכונות התאמה אישית כמו צבע דינמי.

המדריך הזה מתמקד בהעברת אפליקציות מספריית Jetpack‏ Wear Compose Material 2.5‏ (androidx.wear.compose) לספריית Jetpack‏ Wear Compose Material 3‏ (androidx.wear.compose.material3).

גישות

כדי להעביר את קוד האפליקציה מ-M2.5 ל-M3, פועלים לפי אותה גישה שמתוארת במדריך להעברת חומרים מ-Compose לטלפון, ובפרט:

פניות קשורות

ל-M3 יש חבילה וגרסה נפרדות מ-M2.5:

M2.5

implementation("androidx.wear.compose:compose-material:1.4.0")

M3

implementation("androidx.wear.compose:compose-material3:1.8.0-alpha01")

אפשר לראות את הגרסאות האחרונות של M3 בדף הגרסאות של Wear Compose.

בגרסה 1.8.0-alpha01 של ספריית Wear Compose Foundation נוספו כמה רכיבים חדשים שמיועדים לעבודה עם רכיבי Material 3. באופן דומה, SwipeDismissableNavHost מהספרייה Wear Compose Navigation כולל אנימציה מעודכנת כשמריצים אותו ב-Wear OS 6 (רמת API 36) ומעלה. כשמעדכנים לגרסה Wear Compose Material 3, מומלץ לעדכן גם את הספריות Wear Compose Foundation ו-Navigation:

implementation("androidx.wear.compose:compose-foundation:1.8.0-alpha01")
implementation("androidx.wear.compose:compose-navigation:1.8.0-alpha01")

עיצוב

גם ב-M2.5 וגם ב-M3, הפונקציה הניתנת להרכבה של ערכת הנושא נקראת MaterialTheme, אבל חבילות הייבוא והפרמטרים שונים. ב-M3, הפרמטר Colors שונה ל-ColorScheme, והפרמטר MotionScheme נוסף כדי להטמיע מעברים.

M2.5

import androidx.wear.compose.material.MaterialTheme

MaterialTheme(
    colors = AppColors,
    typography = AppTypography,
    shapes = AppShapes,
    content = content
)

M3

import androidx.wear.compose.material3.MaterialTheme
// ...
    MaterialTheme(
        colorScheme = ColorScheme(),
        typography = Typography(),
        shapes = Shapes(),
        motionScheme = MotionScheme.standard(),
        content = { /*content here*/ }
    )

צבע

מערכת הצבעים ב-M3 שונה באופן משמעותי מזו שב-M2.5. מספר הפרמטרים של הצבע גדל, יש להם שמות שונים והם ממופים באופן שונה לרכיבי M3. ב-Compose, ההגדרה הזו חלה על המחלקה M2.5 Colors, על המחלקה M3 ColorScheme ועל פונקציות שקשורות אליהן:

M2.5

import androidx.wear.compose.material.Colors

val appColorScheme: Colors = Colors(
   // M2.5 Color parameters
)

M3

import androidx.wear.compose.material3.ColorScheme
// ...
    val appColorScheme: ColorScheme = ColorScheme(
        // M3 ColorScheme parameters
    )

בטבלה הבאה מפורטים ההבדלים העיקריים בין M2.5 לבין M3:

M2.5 M3
Colors השם שונה ל-ColorScheme
‫13 צבעים ‫29 צבעים
לא רלוונטי ערכות נושא חדשות של צבעים דינמיים
לא רלוונטי צבעים שלישוניים חדשים לביטוי מגוון יותר

עיצוב דינמי של צבעים

תכונה חדשה ב-M3 היא ערכות נושא עם צבעים דינמיים. אם המשתמשים משנים את הצבעים בתצוגת השעון, הצבעים בממשק המשתמש משתנים בהתאם.

אפשר להשתמש בפונקציה dynamicColorScheme כדי להטמיע ערכת צבעים דינמית ולספק defaultColorScheme כגיבוי למקרה שערכת הצבעים הדינמית לא זמינה.

@Composable
fun myApp() {
    val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
    MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {}
}

internal val myBrandColors: ColorScheme = ColorScheme( /* Specify colors here */)

טיפוגרפיה

מערכת הטיפוגרפיה ב-M3 שונה מזו שב-M2.5, והיא כוללת את התכונות הבאות:

  • תשעה סגנונות טקסט חדשים
  • גופנים גמישים, שמאפשרים התאמה אישית של סולמות הסוגים למשקלים, לרוחבים ולעיגולים שונים
  • ‫AnimatedText, שמשתמש בגופנים גמישים

M2.5

import androidx.wear.compose.material.Typography

val Typography = Typography(
   // M2.5 TextStyle parameters
)

M3

import androidx.wear.compose.material3.Typography

val Typography = Typography(
    // M3 TextStyle parameters
)

גופני Flex

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

סגנונות טקסט

אלה סגנונות הטקסט שזמינים ב-M3. הם מופעלים כברירת מחדל על ידי רכיבים שונים של M3.

טיפוגרפיה TextStyle
תצוגה displayLarge, ‏ displayMedium, ‏ displaySmall
כותרת titleLarge, ‏ titleMedium, ‏ titleSmall
תווית labelLarge, ‏ labelMedium, ‏ labelSmall
גוף bodyLarge, ‏ bodyMedium, ‏ bodySmall, ‏ bodyExtraSmall
שם מספר numeralExtraLarge, ‏ numeralLarge, ‏ numeralMedium, ‏ numeralSmall, ‏ numeralExtraSmall
קשת arcLarge, ‏ arcMedium, ‏ arcSmall

צורה

מערכת הצורות ב-M3 שונה מזו שב-M2.5. מספר הפרמטרים של הצורה גדל, השמות שלהם שונים והמיפוי שלהם לרכיבי M3 שונה. אלה הגדלים של הצורות שזמינים:

  • קטן במיוחד
  • קטן
  • בינוני
  • גדול
  • גדול במיוחד

במצב כתיבה, ההגדרה הזו רלוונטית למחלקות M2.5 Shapes ול-M3 Shapes:

M2.5

import androidx.wear.compose.material.Shapes

val Shapes = Shapes(
   // M2.5 Shapes parameters
)

M3

import androidx.wear.compose.material3.Shapes

val Shapes = Shapes(
    // M3 Shapes parameters
)

אפשר להשתמש במיפוי הפרמטרים של הצורות מתוך המאמר בנושא מעבר מ-Material 2 ל-Material 3 ב-Compose כנקודת התחלה.

שינוי צורה

ב-M3 מוצג שינוי צורה: הצורות משתנות בתגובה לאינטראקציות.

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

כפתורים פונקציה של שינוי צורה
IconButton ‫IconButtonDefaults.animatedShapes מפעיל אנימציה של לחצן הסמל בלחיצה
IconToggleButton ‫IconToggleButtonDefaults.animatedShapes יוצר אנימציה ללחצן ההפעלה/ההשבתה של הסמל בלחיצה ו-
IconToggleButtonDefaults.variantAnimatedShapes יוצר אנימציה ללחצן ההפעלה/ההשבתה של הסמל בלחיצה ובסימון/ביטול הסימון
TextButton ‫TextButtonDefaults.animatedShapes מוסיף אנימציה ללחצן הטקסט כשלוחצים עליו
TextToggleButton ‫TextToggleButtonDefaults.animatedShapes מוסיף אנימציה למתג הטקסט כשלוחצים עליו, ו-TextToggleButtonDefaults.variantAnimatedShapes מוסיף אנימציה למתג הטקסט כשלוחצים עליו וכשמסמנים או מבטלים את הסימון שלו.

רכיבים ופריסה

רוב הרכיבים והפריסות מ-M2.5 זמינים ב-M3. עם זאת, חלק מהרכיבים והפריסות של M3 לא היו קיימים ב-M2.5. בנוסף, לחלק מהרכיבים של M3 יש יותר וריאציות מאשר לרכיבים המקבילים ב-M2.5.

יש רכיבים שצריך להתייחס אליהם באופן מיוחד, אבל כנקודת התחלה מומלץ להשתמש במיפויים הבאים של פונקציות:

‫Material 2.5 ‫Material 3
androidx.wear.compose.material.dialog.Alert androidx.wear.compose.material3.AlertDialog
androidx.wear.compose.material.Button ‫androidx.wear.compose.material3.IconButton או androidx.wear.compose.material3.TextButton
androidx.wear.compose.material.Card androidx.wear.compose.material3.Card
androidx.wear.compose.material.TitleCard androidx.wear.compose.material3.TitleCard
androidx.wear.compose.material.AppCard androidx.wear.compose.material3.AppCard
androidx.wear.compose.material.Checkbox אין רכיב מקביל ל-M3, צריך להעביר ל-androidx.wear.compose.material3.CheckboxButton או ל-androidx.wear.compose.material3.SplitCheckboxButton
androidx.wear.compose.material.Chip ‫androidx.wear.compose.material3.Button או
androidx.wear.compose.material3.OutlinedButton או
androidx.wear.compose.material3.FilledTonalButton או
androidx.wear.compose.material3.ChildButton
androidx.wear.compose.material.CompactChip androidx.wear.compose.material3.CompactButton
androidx.wear.compose.material.InlineSlider androidx.wear.compose.material3.Slider
androidx.wear.compose.material.LocalContentAlpha() הוסר כי לא נעשה בו שימוש על ידי Text או Icon ב-Material 3
androidx.wear.compose.material.PositionIndicator androidx.wear.compose.material3.ScrollIndicator
androidx.wear.compose.material.RadioButton אין רכיב מקביל ל-M3, צריך להעביר ל-androidx.wear.compose.material3.RadioButton או ל-androidx.wear.compose.material3.SplitRadioButton
androidx.wear.compose.material.SwipeToRevealCard androidx.wear.compose.material3.SwipeToReveal
androidx.wear.compose.material.SwipeToRevealChip androidx.wear.compose.material3.SwipeToReveal
androidx.wear.compose.material.Scaffold ‫androidx.wear.compose.material3.AppScaffold ו-androidx.wear.compose.material3.ScreenScaffold
androidx.wear.compose.material.SplitToggleChip אין רכיב M3 מקביל, צריך להעביר את הקוד אל androidx.wear.compose.material3.SplitCheckboxButton,‏ androidx.wear.compose.material3.SplitSwitchButton או אל androidx.wear.compose.material3.SplitRadioButton
androidx.wear.compose.material.Switch אין רכיב מקביל ל-M3, צריך להעביר ל-androidx.wear.compose.material3.SwitchButton או ל-androidx.wear.compose.material3.SplitSwitchButton
androidx.wear.compose.material.ToggleButton ‫androidx.wear.compose.material3.IconToggleButton או androidx.wear.compose.material3.TextToggleButton
androidx.wear.compose.material.ToggleChip ‫androidx.wear.compose.material3.CheckboxButton או
androidx.wear.compose.material3.RadioButton או
androidx.wear.compose.material3.SwitchButton
androidx.wear.compose.material.Vignette הוסר כי הוא לא כלול בעיצוב של Material 3 Expressive ל-Wear OS

ריכזנו כאן רשימה של רכיבים נפוצים של Material 3 והרכיבים המקבילים שלהם ב-Material 2.5:

‫Material 3 רכיב מקביל ל-Material 2.5 (אם לא חדש ב-M3)
androidx.wear.compose.material3.AlertDialog androidx.wear.compose.material.dialog.Alert
androidx.wear.compose.material3.AnimatedPage חדש
androidx.wear.compose.material3.AnimatedText חדש
androidx.wear.compose.material3.AppScaffold ‫androidx.wear.compose.material.Scaffold (עם androidx.wear.compose.material3.ScreenScaffold )
androidx.wear.compose.material3.Button androidx.wear.compose.material.Chip
androidx.wear.compose.material3.ButtonGroup חדש
androidx.wear.compose.material3.Card androidx.wear.compose.material.Card
androidx.wear.compose.material3.CheckboxButton ‫androidx.wear.compose.material.ToggleChip עם אמצעי בקרה להחלפת מצב של תיבת סימון
androidx.wear.compose.material3.ChildButton ‫androidx.wear.compose.material.Chip (רק אם לא נדרש רקע)
androidx.wear.compose.material3.CircularProgressIndicator androidx.wear.compose.material.CircularProgressIndicator
androidx.wear.compose.material3.CompactButton androidx.wear.compose.material.CompactChip
androidx.wear.compose.material3.ConfirmationDialog androidx.wear.compose.material.dialog.Confirmation
androidx.wear.compose.material3.curvedText androidx.wear.compose.material.curvedText
androidx.wear.compose.material3.DatePicker חדש
androidx.wear.compose.material3.Dialog androidx.wear.compose.material.dialog.Dialog
androidx.wear.compose.material3.EdgeButton חדש
androidx.wear.compose.material3.FadingExpandingLabel חדש
androidx.wear.compose.material3.FilledTonalButton ‫androidx.wear.compose.material.Chip כשנדרש רקע של כפתור בצבע אחד
androidx.wear.compose.material3.HorizontalPageIndicator androidx.wear.compose.material.HorizontalPageIndicator
androidx.wear.compose.material3.HorizontalPagerScaffold חדש
androidx.wear.compose.material3.Icon androidx.wear.compose.material.Icon
androidx.wear.compose.material3.IconButton androidx.wear.compose.material.Button
androidx.wear.compose.material3.IconToggleButton androidx.wear.compose.material.ToggleButton
androidx.wear.compose.material3.LevelIndicator חדש
androidx.wear.compose.material3.LinearProgressIndicator חדש
androidx.wear.compose.material3.ListHeader androidx.wear.compose.material.ListHeader
androidx.wear.compose.material3.ListSubHeader חדש
androidx.wear.compose.material3.MaterialTheme androidx.wear.compose.material.MaterialTheme
androidx.wear.compose.material3.OpenOnPhoneDialog חדש
androidx.wear.compose.material3.Picker androidx.wear.compose.material.Picker
androidx.wear.compose.material3.PickerGroup androidx.wear.compose.material.PickerGroup
androidx.wear.compose.material3.RadioButton ‫androidx.wear.compose.material.ToggleChip עם מתג כפתור בחירה
androidx.wear.compose.material3.ScreenScaffold ‫androidx.wear.compose.material.Scaffold (עם androidx.wear.compose.material3.AppScaffold)
androidx.wear.compose.material3.ScrollIndicator androidx.wear.compose.material.PositionIndicator
androidx.wear.compose.material3.scrollAway androidx.wear.compose.material.scrollAway
androidx.wear.compose.material3.SegmentedCircularProgressIndicator חדש
androidx.wear.compose.material3.Slider androidx.wear.compose.material.InlineSlider
androidx.wear.compose.material3.SplitRadioButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.SplitCheckboxButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.SplitSwitchButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.Stepper androidx.wear.compose.material.Stepper
androidx.wear.compose.material3.SwipeToDismissBox androidx.wear.compose.material.SwipeToDismissBox
androidx.wear.compose.material3.SwipeToReveal ‫androidx.wear.compose.material.SwipeToRevealCard ו-androidx.wear.compose.material.SwipeToRevealChip
androidx.wear.compose.material3.SwitchButton ‫androidx.wear.compose.material.ToggleChip עם אמצעי בקרה למיתוג
androidx.wear.compose.material3.Text androidx.wear.compose.material.Text
androidx.wear.compose.material3.TextButton androidx.wear.compose.material.Button
androidx.wear.compose.material3.TextToggleButton androidx.wear.compose.material.ToggleButton
androidx.wear.compose.material3.TimeText androidx.wear.compose.material.TimeText
androidx.wear.compose.material3.VerticalPagerScaffold חדש

ולבסוף, רשימה של כמה רכיבים רלוונטיים מהספרייה Wear Compose Foundation:

‫Wear Compose Foundation 1.8.0-alpha01
androidx.wear.compose.foundation.hierarchicalFocusGroup משמש להוספת הערות לתכנים קומפוזביליים באפליקציה, כדי לעקוב אחרי החלק הפעיל של הקומפוזיציה ולתאם את המיקוד.
androidx.wear.compose.foundation.pager.HorizontalPager רכיב pager עם גלילה אופקית, שמבוסס על רכיבי Compose Foundation עם שיפורים ספציפיים ל-Wear כדי לשפר את הביצועים ולעמוד בהנחיות של Wear OS.
androidx.wear.compose.foundation.pager.VerticalPager רכיב pager עם גלילה אנכית, שמבוסס על רכיבי Compose Foundation עם שיפורים ספציפיים ל-Wear כדי לשפר את הביצועים ולעמוד בהנחיות של Wear OS.
androidx.wear.compose.foundation.lazy.TransformingLazyColumn אפשר להשתמש במקום ScalingLazyColumn כדי להוסיף לכל פריט אפקטים של שינוי צורה בזמן גלילה.

כפתורים

הלחצנים ב-M3 שונים מאלה שב-M2.5. הצ'יפ M2.5 הוחלף בלחצן. ההטמעה של Button מספקת ערכי ברירת מחדל לText, maxLines וtextAlign. אפשר לשנות את ערכי ברירת המחדל האלה ברכיב Text.

M2.5

import androidx.wear.compose.material.Chip

//M2.5 Buttons
Chip(...)
CompactChip(...)
Button(...)

M3

//M3 Buttons
Button(onClick = { }){}
CompactButton(onClick = { }){}
IconButton(onClick = { }){}
TextButton(onClick = { }){}

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

ב-M3 מוצג כפתור חדש: EdgeButton. ‫EdgeButton זמין ב-4 מידות שונות: אקסטרה סמול, סמול, מדיום ולרג'. ההטמעה של EdgeButton מספקת ערך ברירת מחדל ל-maxLines בהתאם לגודל, ואפשר להתאים אותו אישית.

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

val state = rememberTransformingLazyColumnState()
ScreenScaffold(
    scrollState = state,
    edgeButton = {
        EdgeButton(
            onClick = { },
            modifier = Modifier.scrollable(
                state,
                orientation = Orientation.Vertical,
                reverseDirection = true,
                // Apply overscroll to the EdgeButton for proper scrolling behavior.
                overscrollEffect = rememberOverscrollEffect(),
            ),
        ) {
            Text(stringResource(R.string.show))
        }
    },
) { contentPadding ->
    TransformingLazyColumn(state = state, contentPadding = contentPadding) {
        // additional code here
        // ...
    }
}

פיגום

ה-Scaffold ב-M3 שונה מזה שב-M2.5. ב-M3, ‏ AppScaffold ורכיב ה-Composable החדש ScreenScaffold החליפו את Scaffold. הרכיבים AppScaffold ו-ScreenScaffold מגדירים את המבנה של המסך ומתאמים את המעברים של הרכיבים ScrollIndicator ו-TimeText.

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

מצהירים על AppScaffold אחד לפעילות ומשתמשים ב-ScreenScaffold לכל מסך. ‫AppScaffold מוסיף רכיב ברירת מחדל TimeText למסכים. אפשר לשנות את ברירת המחדל באמצעות הפרמטר timeText.

M2.5

import androidx.wear.compose.material.Scaffold

Scaffold {...}

M3

    AppScaffold {
        val navController = rememberSwipeDismissableNavController()
        SwipeDismissableNavHost(
            navController = navController,
            startDestination = "message_list"
        ) {
            composable("message_list") {
                MessageList(onMessageClick = { id ->
                    navController.navigate("message_detail/$id")
                })
            }
            composable("message_detail/{id}") {
                MessageDetail(id = it.arguments?.getString("id")!!)
            }
        }
    }
}

// Implementation of one of the screens in the navigation
@Composable
fun MessageDetail(id: String) {
    // .. Screen level content goes here
    val scrollState = rememberTransformingLazyColumnState()
    val transformationSpec = rememberTransformationSpec()

    ScreenScaffold(
        scrollState = scrollState,
    ) { contentPadding ->
        // Screen content goes here
        // ...

אם אתם משתמשים ב-HorizontalPager עם HorizontalPageIndicator, אתם יכולים לעבור ל-HorizontalPagerScaffold. ‫HorizontalPagerScaffold מוצב בתוך AppScaffold. הרכיבים AppScaffold ו-HorizontalPagerScaffold מציגים את המבנה של רכיב Pager ומתאמים את המעברים של הרכיבים HorizontalPageIndicator ו-TimeText.

HorizontalPagerScaffold מוצג כברירת מחדל במרכז הקצה של המסך, והוא מתאם את ההצגה וההסתרה של TimeText ושל HorizontalPageIndicator בהתאם לכך שמתבצעת החלפה של דפים ב-Pager. הפעולה הזו נקבעת על ידי PagerState.HorizontalPageIndicator

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

AppScaffold {
    val pagerState = rememberPagerState(pageCount = { 10 })

    HorizontalPagerScaffold(pagerState = pagerState) {
        HorizontalPager(
            state = pagerState,
            flingBehavior =
                PagerScaffoldDefaults.snapWithSpringFlingBehavior(
                    state = pagerState
                ),
        ) { page ->
            AnimatedPage(pageIndex = page, pagerState = pagerState) {
                val columnState = rememberTransformingLazyColumnState()
                val transformationSpec = rememberTransformationSpec()

                ScreenScaffold(
                    scrollState = columnState,
                ) { contentPadding ->
                    TransformingLazyColumn(
                        state = columnState,
                        contentPadding = contentPadding,
                    ) {
                        item {
                            ListHeader(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .transformedHeight(this, transformationSpec)
                                    .minimumVerticalContentPadding(
                                        ListHeaderDefaults.minimumTopListContentPadding
                                    ),
                                transformation = SurfaceTransformation(transformationSpec),
                            ) {
                                Text(text = "Pager sample")
                            }
                        }
                        item {
                            Card(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .transformedHeight(this, transformationSpec)
                                    .minimumVerticalContentPadding(
                                        CardDefaults.minimumVerticalListContentPadding
                                    ),
                                transformation = SurfaceTransformation(transformationSpec),
                            ) {
                                if (page == 0) {
                                    Text(text = "Page #$page. Swipe right")
                                } else {
                                    Text(text = "Page #$page. Swipe left and right")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

לבסוף, ב-M3 מוצג VerticalPagerScaffold שפועל לפי אותו דפוס כמו HorizontalPagerScaffold:

@Composable
fun VerticalPagerScaffoldSample() {
    AppScaffold {
        val pagerState = rememberPagerState(pageCount = { 10 })

        VerticalPagerScaffold(pagerState = pagerState) {
            VerticalPager(
                state = pagerState,
                flingBehavior =
                    PagerScaffoldDefaults.snapWithSpringFlingBehavior(
                        state = pagerState
                    ),
            ) { page ->
                AnimatedPage(pageIndex = page, pagerState = pagerState) {
                    ScreenScaffold {
                        Column(
                            modifier = Modifier.fillMaxSize(),
                            horizontalAlignment = Alignment.CenterHorizontally,
                            verticalArrangement = Arrangement.Center,
                        ) {
                            Text(text = "Page #$page")
                            Spacer(modifier = Modifier.height(8.dp))
                            Text(text = "Swipe up and down")
                        }
                    }
                }
            }
        }
    }
}

Placeholder

יש כמה שינויים ב-API בין M2.5 ל-M3. ‫M3 כולל שני משני placeholder:

  • ‫Modifier.placeholder, שמוצג במקום תוכן שעדיין לא נטען
  • אפקט נצנוץ של placeholder‏ Modifier.placeholderShimmer שפועל בלולאת אנימציה בזמן ההמתנה לטעינת הנתונים.

בטבלה הבאה מפורטים שינויים נוספים ברכיב Placeholder.

M2.5 M3
PlaceholderState.startPlaceholderAnimation הוסר
PlaceholderState.placeholderProgression הוסר
PlaceholderState.isShowContent הוחלף על ידי PlaceholderState.isVisible (ערך בוליאני הפוך)
PlaceholderState.isWipeOff הוסר
PlaceholderDefaults.painterWithPlaceholderOverlayBackgroundBrush הוסר
PlaceholderDefaults.placeholderBackgroundBrush הוסר
PlaceholderDefaults.placeholderChipColors הוסר

SwipeDismissableNavHost

‫SwipeDismissableNavHost הוא חלק מ-wear.compose.navigation. כשמשתמשים ברכיב הזה עם M3, ‏ M3 MaterialTheme מעדכן את LocalSwipeToDismissBackgroundScrimColor ואת LocalSwipeToDismissContentScrimColor.

‫TransformingLazyColumn

‫TransformingLazyColumn הוא חלק מ-androidx.wear.compose.foundation.lazy ומוסיף תמיכה בהתאמת גודל ובאנימציות של שינוי צורה בפריטים ברשימה במהלך הגלילה, כדי לשפר את חוויית המשתמש. מומלץ מאוד להעביר את האפליקציות מ-ScalingLazyColumn ל-TransformingLazyColumn.

בדומה ל-ScalingLazyColumn, הוא מספק rememberTransformingLazyColumnState() כדי ליצור TransformingLazyColumnState שנזכר בכל ההודעות.

כדי להוסיף אנימציות של שינוי גודל ושינוי צורה, מוסיפים את הפרטים הבאים לכל פריט ברשימה:

  • ‫Modifier.transformedHeight, שמאפשרת לכם לחשב את הגובה של הפריטים אחרי השינוי באמצעות TransformationSpec, אתם יכולים להשתמש ב-rememberTransformationSpec() אלא אם אתם צריכים התאמה אישית נוספת.
  • ‫SurfaceTransformation

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

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(
    scrollState = columnState
) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding
    ) {
        item {
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        imageVector = Icons.Default.Build,
                        contentDescription = "build",
                    )
                },
            ) {
                Text(
                    text = "Build",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
    }
}

כדי לקבל מידע נוסף על מעבר מ-M2.5 ל-M3 ב-Compose, אפשר לעיין במקורות המידע הנוספים הבאים.

דוגמאות

מאמרי העזרה של ה-API וקוד מקור

עיצוב