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 Material לטלפון, ובמיוחד:
- לא מומלץ להשתמש גם ב-M2.5 וגם ב-M3 באפליקציה אחת לטווח ארוך.
- אתם לא צריכים יותר להשתמש בספריות Horologist Composables, Compose Layout או Compose Material. במקום זאת, השתמשו ברכיבים ב-M3.
- להשתמש בגישה הדרגתית.
פניות קשורות
ל-M3 יש חבילה וגרסה נפרדות מ-M2.5:
M2.5
implementation("androidx.wear.compose:compose-material:1.4.0")
M3
implementation("androidx.wear.compose:compose-material3:1.8.0-alpha02")
גרסאות M3 העדכניות מפורטות בדף הגרסאות של Wear Compose.
בגרסה 1.8.0-alpha02 של ספריית 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-alpha02")
implementation("androidx.wear.compose:compose-navigation:1.8.0-alpha02")
עיצוב
גם ב-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, זה רלוונטי למחלקה Colors של M2.5, למחלקה ColorScheme של M3 ולפונקציות שקשורות אליהן:
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
גופנים גמישים מאפשרים למעצבים לציין את הרוחב והמשקל של הגופן לגדלים ספציפיים.
סגנונות טקסט
האובייקטים הבאים של TextStyles זמינים ב-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. אפשר לבחור את הגדלים הבאים של הצורות:
- קטנה במיוחד
- קטן
- בינוני
- גדול
- גדול מאוד
ב-Compose, זה רלוונטי למחלקה Shapes ב-M2.5 ולמחלקה Shapes ב-M3:
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 )
כנקודת התחלה, אפשר להשתמש במיפוי הפרמטרים של Shapes מהעברה מ-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 3 והרכיבים המקבילים להם ב-Material 2.5:
ולסיום, רשימה של כמה רכיבים רלוונטיים מספריית Wear Compose Foundation:
| Wear Compose Foundation 1.8.0-alpha02 | |
|---|---|
| androidx.wear.compose.foundation.hierarchicalFocusGroup | משמש להוספת הערות לתכנים קומפוזביליים באפליקציה, כדי לעקוב אחרי החלק הפעיל של הקומפוזיציה ולתאם את המיקוד. |
| androidx.wear.compose.foundation.pager.HorizontalPager | כלי לדפדוף אופקי, שמבוסס על רכיבי Compose Foundation עם שיפורים ספציפיים ל-Wear כדי לשפר את הביצועים ואת ההתאמה להנחיות של Wear OS. |
| androidx.wear.compose.foundation.pager.VerticalPager | כלי לדפדוף אנכי, שמבוסס על רכיבי 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 // ... } }
פיגום
הפיגום ב-M3 שונה מזה שב-M2.5. ב-M3, AppScaffold והרכיב החדש ScreenScaffold החליפו את Scaffold. AppScaffold ו-ScreenScaffold מגדירים את מבנה המסך ומתאמים את המעברים של הרכיבים ScrollIndicator ו-TimeText.
AppScaffold מאפשר לרכיבי מסך סטטיים כמו TimeText להישאר גלויים במהלך מעברים בתוך האפליקציה, כמו החלקה לסגירה. הוא מספק משבצת לתוכן הראשי של האפליקציה, שבדרך כלל יסופק על ידי רכיב ניווט כמו SwipeDismissableNavHost
מצהירים על AppScaffold אחד ל-Activity ומשתמשים ב-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 קובעים את המבנה של הכלי לדפדוף ומתאמים את המעברים של הרכיבים HorizontalPageIndicator ו-TimeText.
כברירת מחדל, HorizontalPagerScaffold מציג את HorizontalPageIndicator במרכז החלק התחתון של המסך, ומתאם את ההצגה וההסתרה של TimeText ו-HorizontalPageIndicator בהתאם לשאלה אם Pager עובר דפדוף, וזה נקבע על ידי PagerState.
יש גם רכיב AnimatedPage חדש, שמוסיף אנימציה לדף בתוך Pager עם אפקט של שינוי קנה מידה ו-scrim על סמך המיקום שלו.
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 יש שני משתני פלייסהולדר:
-
Modifier.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, MaterialTheme של M3 מעדכן את 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, אפשר לעיין במקורות המידע הנוספים הבאים.