ב-Jetpack Compose יש הטמעה של עיצוב חדשני תלת-ממדי, מערכת עיצוב מקיפה ליצירת ממשקים דיגיטליים. רכיבי Material Design (לחצנים, כרטיסים, מתגים וכו') מבוססים על עיצוב לפי נושאים ב-Material, שהיא דרך שיטתית להתאמה אישית של Material Design כך שישקף טוב יותר את המותג של המוצר. חומר לימוד העיצוב כולל את מאפייני הצבע, טיפוגרפיה והצורה. כאשר אתם מתאימים אישית את ההגדרות האלה שלך, השינויים שלך ישתקפו באופן אוטומטי ברכיבים שבהם אתה משתמש כדי לפתח את האפליקציה.
ב-Jetpack Compose, המושגים האלה מיושמים באמצעות ה-composable MaterialTheme
:
MaterialTheme( colors = // ... typography = // ... shapes = // ... ) { // app content }
מגדירים את הפרמטרים ששולחים אל MaterialTheme
כדי להגדיר את העיצוב של האפליקציה.
איור 1. בצילום המסך הראשון רואים אפליקציה שלא מוגדרת
MaterialTheme
, ולכן נעשה בו שימוש בעיצוב ברירת המחדל. בצילום המסך השני רואים
אפליקציה שמעבירה פרמטרים אל MaterialTheme
כדי להתאים אישית את הסגנון.
צבע
הצבעים מוגדרים ב-Compose באמצעות הכיתה Color
, שהיא כיתה פשוטה לאחסון נתונים.
val Red = Color(0xffff0000) val Blue = Color(red = 0f, green = 0f, blue = 1f)
אתם יכולים לארגן אותם איך שתרצו (כקבועים ברמה העליונה, במסגרת סינגלטון או מוגדר בתוך השורה), אנחנו ממליצים מאוד לציין צבעים את העיצוב ומאחזר את הצבעים. הגישה הזו מאפשרת לתמוך בקלות בעיצוב כהה ובעיצובים בתצוגת עץ.
איור 2. מערכת הצבעים של Material.
Compose מספק את הכיתה Colors
כדי ליצור מודל של מערכת הצבעים של Material. ב-Colors
יש פונקציות build ליצירת קבוצות של צבעים בהירים או כהים:
private val Yellow200 = Color(0xffffeb46) private val Blue200 = Color(0xff91a4fc) // ... private val DarkColors = darkColors( primary = Yellow200, secondary = Blue200, // ... ) private val LightColors = lightColors( primary = Yellow500, primaryVariant = Yellow400, secondary = Blue700, // ... )
אחרי שמגדירים את Colors
, אפשר להעביר אותם ל-MaterialTheme
:
MaterialTheme( colors = if (darkTheme) DarkColors else LightColors ) { // app content }
שימוש בצבעי עיצוב
אפשר לאחזר את Colors
שסופק ל-MaterialTheme
באמצעות MaterialTheme.colors
.
Text( text = "Hello theming", color = MaterialTheme.colors.primary )
הצבע של פני השטח והתוכן
רכיבים רבים מקבלים צבע וצבע תוכן:
Surface( color = MaterialTheme.colors.surface, contentColor = contentColorFor(color), // ... ) { /* ... */ } TopAppBar( backgroundColor = MaterialTheme.colors.primarySurface, contentColor = contentColorFor(backgroundColor), // ... ) { /* ... */ }
כך תוכלו לא רק להגדיר את הצבע של רכיב ה-Composable, אלא גם לספק צבע ברירת מחדל לתוכן, לרכיבי ה-Composable שמכיל. הרבה
בתכנים קומפוזביליים משתמשים בצבע התוכן הזה כברירת מחדל. לדוגמה, הצבע של Text
מבוסס על צבע התוכן של האב, ו-Icon
משתמש בצבע הזה כדי להגדיר את הגוון שלו.
איור 3. הגדרת צבעי רקע שונים יוצרת צבעים שונים של טקסט וסמלים.
contentColorFor()
מאחזרת את ה-"on" המתאים
לכל צבעי העיצוב. לדוגמה, אם מגדירים צבע רקע primary
ב-Surface
, המערכת משתמשת בפונקציה הזו כדי להגדיר את onPrimary
כצבע התוכן. אם מגדירים צבע רקע שאינו צבע העיצוב, צריך לציין גם צבע תוכן מתאים. שימוש ב-LocalContentColor
כדי לאחזר את צבע התוכן המועדף לרקע הנוכחי,
במיקום נתון בהיררכיה.
אלפא של תוכן
לרוב כדאי לשנות את מידת הדגשת התוכן כדי להעביר את מידת החשיבות שלו ולספק היררכיה חזותית. ההמלצות לגבי ניראות הטקסט ב-Material Design ממליצות להשתמש ברמות שונות של שקיפות כדי להעביר רמות שונות של חשיבות.
ב-Jetpack פיתוח נייטיב הדבר מיושם באמצעות LocalContentAlpha
.
כדי לציין אלפא של תוכן להיררכיה, מספקים ערך ל-CompositionLocal
הזה.
בתוך עץ
תכנים קומפוזביליים יכולים להשתמש בערך הזה כדי להחיל את טיפול האלפא על התוכן שלהם.
לדוגמה, כברירת מחדל, ב-Text
וב-Icon
נעשה שימוש בשילוב של LocalContentColor
עם התאמה לשימוש ב-LocalContentAlpha
. מאפיין החומר מציין כמה ערכים רגילים של אלפא (high
, medium
, disabled
) שמתבססים על האובייקט ContentAlpha
.
// By default, both Icon & Text use the combination of LocalContentColor & // LocalContentAlpha. De-emphasize content by setting content alpha CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) { Text( // ... ) } CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) { Icon( // ... ) Text( // ... ) }
למידע נוסף על CompositionLocal
, כדאי לעיין בנתונים בהיקף מקומי עם
מדריך מקומי של יצירה.
איור 4. השתמשו ברמות שונות של הדגשה בטקסט כדי להעביר באופן חזותי את היררכיית המידע. שורת הטקסט הראשונה היא הכותרת, והיא מכילה את המידע החשוב ביותר, ולכן נעשה בה שימוש ב-ContentAlpha.high
. השורה השנייה מכילה מטא-נתונים פחות חשובים, ולכן נעשה בה שימוש ב-ContentAlpha.medium
.
עיצוב כהה
כדי להטמיע עיצוב בהיר ועיצוב כהה, מזינים קבוצות שונות של תכנים
Colors
לתוכן הקומפוזבילי MaterialTheme
:
@Composable fun MyTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { MaterialTheme( colors = if (darkTheme) DarkColors else LightColors, /*...*/ content = content ) }
בדוגמה הזו, MaterialTheme
מוקף בפונקציה קומפוזבילית משלו,
שמקבל פרמטר שמציין אם להשתמש בעיצוב כהה או לא. לחשבון
במקרה הזה, הפונקציה מקבלת את ערך ברירת המחדל של darkTheme
על ידי שליחת שאילתה על
הגדרת העיצוב של המכשיר.
אפשר להשתמש בקוד כמו בדוגמה הבאה כדי לבדוק אם הערכים של Colors
הנוכחיים הם בהירים או כהים:
val isLightTheme = MaterialTheme.colors.isLight Icon( painterResource( id = if (isLightTheme) { R.drawable.ic_sun_24 } else { R.drawable.ic_moon_24 } ), contentDescription = "Theme" )
שכבות-על
בעיצוב Material, משטחים בעיצובים כהים עם רמות גבוהות יותר מקבלים שכבות-על של רמה, שמבהירות את הרקע שלהם. ככל שהמשטח גבוה יותר (ככל שהוא קרוב יותר למקור אור משתמע), הוא יהפוך לבהיר יותר.
שכבות-העל האלה חלות באופן אוטומטי על ה-composable Surface
כשמשתמשים בצבעים כהים, ועל כל composable אחר של Material שבו נעשה שימוש בשטח:
Surface( elevation = 2.dp, color = MaterialTheme.colors.surface, // color will be adjusted for elevation /*...*/ ) { /*...*/ }
איור 5. הכרטיסים והניווט התחתון כוללים את הצבע surface
בתור הרקע שלהם. מכיוון שהכרטיסים והניווט התחתון שונים זה מזה
רמות גובה מעל הרקע, הן שונות במקצת
צבעים - הכרטיסים בהירים יותר מהרקע והניווט התחתון
קל יותר מהקלפים.
בתרחישים בהתאמה אישית שלא כוללים Surface
, צריך להשתמש בפונקציה
LocalElevationOverlay
,
CompositionLocal
שמכיל את
ElevationOverlay
בשימוש על ידי
Surface
רכיבים:
// Elevation overlays // Implemented in Surface (and any components that use it) val color = MaterialTheme.colors.surface val elevation = 4.dp val overlaidColor = LocalElevationOverlay.current?.apply( color, elevation )
כדי להשבית שכבות-על של הרשאות גישה, מציינים את הערך null
בנקודה הרצויה בהיררכיה שניתן ליצור ממנה קומפוזיציות:
MyTheme { CompositionLocalProvider(LocalElevationOverlay provides null) { // Content without elevation overlays } }
הגבלה של סימוני צבע
ב-Material מומלץ להשתמש בצבעים מודגשים מוגבלים בעיצובים כהים, ולרוב עדיף להשתמש בצבע surface
במקום בצבע primary
. רכיבים מורכבים של Material, כמו TopAppBar
ו-BottomNavigation
, מטמיעים את ההתנהגות הזו כברירת מחדל.
איור 6. עיצוב חומר כהה עם נגיעות צבע מוגבלות. בסרגל האפליקציות העליון נעשה שימוש בצבע הראשי בעיצוב בהיר, ובצבע פני השטח בעיצוב כהה.
לתרחישים מותאמים אישית, השתמשו primarySurface
מאפיין לתוסף:
Surface( // Switches between primary in light theme and surface in dark theme color = MaterialTheme.colors.primarySurface, /*...*/ ) { /*...*/ }
טיפוגרפיה
ב-Material מוגדר סוג מערכת, שמעודד אתכם להשתמש במספר קטן של סגנונות עם שמות סמנטיים.
איור 7. המערכת של סוג החומר.
מערכת Compose מטמיעה את מערכת הסוגים באמצעות המחלקות Typography
, TextStyle
וfont-related. ה-constructor של Typography
מציע הגדרות ברירת מחדל לכל סגנון, כך שתוכלו להשמיט סגנונות שאתם לא רוצים להתאים אישית:
val raleway = FontFamily( Font(R.font.raleway_regular), Font(R.font.raleway_medium, FontWeight.W500), Font(R.font.raleway_semibold, FontWeight.SemiBold) ) val myTypography = Typography( h1 = TextStyle( fontFamily = raleway, fontWeight = FontWeight.W300, fontSize = 96.sp ), body1 = TextStyle( fontFamily = raleway, fontWeight = FontWeight.W600, fontSize = 16.sp ) /*...*/ ) MaterialTheme(typography = myTypography, /*...*/) { /*...*/ }
אם רוצים להשתמש באותו משפחת גופנים, ציינו את
defaultFontFamily parameter
ולהשמיט את fontFamily
של רכיבי TextStyle
:
val typography = Typography(defaultFontFamily = raleway) MaterialTheme(typography = typography, /*...*/) { /*...*/ }
שימוש בסגנונות טקסט
ניתן לגשת ל-TextStyle
דרך MaterialTheme.typography
. אחזור הערכים של TextStyle
:
Text( text = "Subtitle2 styled", style = MaterialTheme.typography.subtitle2 )
איור 8. אפשר להשתמש במגוון גופנים וסגנונות כדי להביע את המותג שלכם.
צורה
מערכת הרכיבים של Material מגדירה מערכת צורות, שמאפשרת להגדיר צורות לרכיבים גדולים, בינוניים וקטנים.
איור 9. מערכת הצורה מסוג Material Design.
Compose מקטע מיישם את מערכת הצורה עם
Shapes
, שמאפשרת
מציינים
CornerBasedShape
לכל קטגוריית מידות:
val shapes = Shapes( small = RoundedCornerShape(percent = 50), medium = RoundedCornerShape(0f), large = CutCornerShape( topStart = 16.dp, topEnd = 0.dp, bottomEnd = 0.dp, bottomStart = 16.dp ) ) MaterialTheme(shapes = shapes, /*...*/) { /*...*/ }
הרבה רכיבים משתמשים בצורות האלה כברירת מחדל. לדוגמה, הערכים Button
, TextField
ו-FloatingActionButton
מוגדרים כברירת מחדל כקטנים, הערכים AlertDialog
מוגדרים כברירת מחדל כבינוניים והערכים ModalDrawer
מוגדרים כברירת מחדל כגדולים. המיפוי המלא מופיע במאמר העזרה בנושא סכמות של צורות.
שימוש בצורות
ניתן לגשת ל-Shape
דרך MaterialTheme.shapes
. אחזור של Shape
s באמצעות קוד:
Surface( shape = MaterialTheme.shapes.medium, /*...*/ ) { /*...*/ }
איור 10. משתמשים בצורות כדי להביע מותג או מצב.
סגנונות ברירת מחדל
אין קונספט מקביל בשדה 'פיתוח' סגנונות ברירת מחדל מ-Android Views. כדי לספק פונקציונליות דומה, אפשר ליצור פונקציות מורכבות משלכם שאפשר לשלב ביניהן, שמקיפות רכיבי Material. לדוגמה, כדי ליצור סגנון של לחצנים, צריך לתחום לחצן בפונקציה קומפוזבילית משלכם, להגדיר באופן ישיר את הפרמטרים שרוצים לשנות ולחשוף אחרים כפרמטרים לתוכן הקומפוזבילי שמכיל את התוכן.
@Composable fun MyButton( onClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Button( colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.secondary ), onClick = onClick, modifier = modifier, content = content ) }
שכבות-על של עיצוב
כדי ליצור את המקבילה לשכבות-על של עיצוב מ-Android Views ב-Compose, אפשר להטמיע רכיבי Compose של MaterialTheme
. מכיוון שהצבעים, הגופנים והצורות מוגדרים כברירת מחדל ב-MaterialTheme
לערך העיצוב הנוכחי, אם העיצוב מגדיר רק אחד מהפרמטרים האלה, הפרמטרים האחרים ימשיכו לשמור על ערכי ברירת המחדל שלהם.
בנוסף, כשעוברים ממסכים מבוססי-תצוגה ל-Compose, חשוב לשים לב לשימושים במאפיין android:theme
. סביר להניח שדרושה לך
MaterialTheme
בחלק הזה של עץ ממשק המשתמש של הכתיבה.
בדוגמה הזו, במסך הפרטים נעשה שימוש ב-PinkTheme
ברוב המסך, ואז ב-BlueTheme
בקטע הקשור. ראו את צילום המסך והקוד בהמשך.
איור 11. עיצובים בתצוגת עץ.
@Composable fun DetailsScreen(/* ... */) { PinkTheme { // other content RelatedSection() } } @Composable fun RelatedSection(/* ... */) { BlueTheme { // content } }
מצבי רכיבים
לרכיבי Material שאפשר לבצע איתם פעולות (לחיצה, החלפת מצב וכו') יכולים להיות מצבים חזותיים שונים. המצבים כוללים מופעל, מושבת, לוחץ וכו'.
לרכיבים מורכבים יש בדרך כלל פרמטר enabled
. הגדרה של הערך false
מונעת אינטראקציה, ומשנה מאפיינים כמו צבע וגובה כדי להעביר באופן חזותי את מצב הרכיב.
איור 12. לחצן עם enabled = true
(שמאל) ו-enabled = false
(ימין).
ברוב המקרים אפשר להסתמך על ברירות המחדל לערכים כמו צבע וגובה. אם רוצים להגדיר ערכים שנעשה בהם שימוש במצבים שונים, יש זמינות כיתות ופונקציות נוחות. לחצן לדוגמה:
Button( onClick = { /* ... */ }, enabled = true, // Custom colors for different states colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.secondary, disabledBackgroundColor = MaterialTheme.colors.onBackground .copy(alpha = 0.2f) .compositeOver(MaterialTheme.colors.background) // Also contentColor and disabledContentColor ), // Custom elevation for different states elevation = ButtonDefaults.elevation( defaultElevation = 8.dp, disabledElevation = 2.dp, // Also pressedElevation ) ) { /* ... */ }
איור 13. לחצן עם enabled = true
(שמאל) ו-enabled = false
(ימין), עם ערכי צבע וגובה מותאמים.
אדוות
רכיבי Material משתמשים בתנודות כדי לציין שהמשתמשים מבצעים איתם אינטראקציה. אם המיקום
נעשה שימוש ב-MaterialTheme
בהיררכיה, Ripple
ישמש בתור
ברירת מחדלIndication
בתוך מגבילים כמו
clickable
וגם
indication
.
ברוב המקרים אפשר להסתמך על ברירת המחדל Ripple
. אם תרצו להגדיר
תוכלו להשתמש במראה שלהם
RippleTheme
כדי לשנות מאפיינים כמו צבע ואלפא.
אפשר להרחיב את RippleTheme
ולהשתמש בפונקציות השירות defaultRippleColor
ו-defaultRippleAlpha
. לאחר מכן, אפשר לספק את העיצוב של 'גלי Google' בהתאמה אישית בהיררכיה באמצעות
LocalRippleTheme
@Composable fun MyApp() { MaterialTheme { CompositionLocalProvider( LocalRippleTheme provides SecondaryRippleTheme ) { // App content } } } @Immutable private object SecondaryRippleTheme : RippleTheme { @Composable override fun defaultColor() = RippleTheme.defaultRippleColor( contentColor = MaterialTheme.colors.secondary, lightTheme = MaterialTheme.colors.isLight ) @Composable override fun rippleAlpha() = RippleTheme.defaultRippleAlpha( contentColor = MaterialTheme.colors.secondary, lightTheme = MaterialTheme.colors.isLight ) }
איור 14. לחצנים עם ערכי הדים שונים שסופקו דרך RippleTheme
.
מידע נוסף
למידע נוסף על נושאי Material ב-Compose, תוכלו לעיין במקורות המידע הנוספים הבאים.
Codelabs
סרטונים
מומלץ עבורך
- הערה: טקסט הקישור מוצג כאשר JavaScript מושבת
- מערכות עיצוב בהתאמה אישית ב-Compose
- העברה מחומר 2 לחומר 3 ב-Compose
- נגישות ב-Compose