העברת עיצובים ב-XML ל-Material 3 ב-Compose

כשמשתמשים בפיתוח נייטיב באפליקציה קיימת, צריך להעביר את ערכות העיצוב של Material XML כדי להשתמש ב-MaterialTheme לרכיבי פיתוח נייטיב. כלומר, לתימה של האפליקציה יהיו שני מקורות אמת: התימה שמבוססת על View והתימה של Compose. כל שינוי בסגנון צריך להתבצע בכמה מקומות. אחרי שהאפליקציה תעבור מיגרציה מלאה ל-Compose, צריך להסיר את העיצוב של ה-XML.

אפשר להשתמש בכלי Material Theme Builder כדי להעביר צבעים.

כשמתחילים את ההעברה מ-XML ל-Compose, מעבירים את העיצוב ל-Material 3 Compose.

מילון מונחים

מונח הגדרה
MaterialTheme הפונקציה הניתנת להגדרה שמספקת עיצוב (צבעים, טיפוגרפיה, צורות) לרכיבי ממשק המשתמש של Compose.
Shape אובייקט Compose שמשמש להגדרת צורות של רכיבים בהתאמה אישית עבור MaterialTheme.
Typography אובייקט Compose שמשמש להגדרת סגנונות טקסט מותאמים אישית (משפחות גופנים, גדלים, משקלים) עבור MaterialTheme.
Color אובייקט Compose שמשמש להגדרת ערכות צבעים מותאמות אישית ל-MaterialTheme.
עיצוב XML מערכת העיצוב של Android מוגדרת בקובצי XML ומשמשת את מערכת התצוגה.

מגבלות

לפני שמבצעים את ההעברה, חשוב להביא בחשבון את המגבלות הבאות:

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

שלב 1: הערכת מערכת העיצוב

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

שלב 2: זיהוי קובצי המקור של העיצוב

ב-XML כותבים ?attr/colorPrimary. ב-Compose, ניגשים לערכי העיצוב באמצעות MaterialTheme.*:

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

אפשר לעשות שימוש חוזר במשאבים כמו מחרוזות, ולא צריך להעביר אותם.

שלב 3: העברת צבעים

עיקרון מרכזי: ב-XML משתמשים בצבעים הקסדצימליים עם שמות. ב-Material 3 נעשה שימוש בתפקידים סמנטיים (למשל, primary, onPrimary, surface). אל תתנו לצבעים שמות לפי הקוד ההקסדצימלי שלהם, אלא לפי התפקיד שלהם.

דוגמאות:

שם הצבע ב-XML תפקיד Material 3
colorPrimary primary
colorPrimaryDark מתוך colorPrimaryVariant primaryContainer או secondary
colorAccent secondary או tertiary
colorOnPrimary onPrimary
android:colorBackground background
colorSurface surface
colorOnSurface onSurface
colorError error
colorOnError onError
colorOutline outline
colorSurfaceVariant surfaceVariant
colorOnSurfaceVariant onSurfaceVariant

מעבירים את ערכות הצבעים הכהות והבהירות מ-XML למקבילות שלהן ב-Material 3 Compose.

שלב 4: העברה של צורות וטיפוגרפיה בהתאמה אישית

  • אם האפליקציה משתמשת בצורות בהתאמה אישית:

    1. בקטע הקוד של Compose, מגדירים אובייקט Shape כדי לשכפל את הגדרות הצורה של ה-XML.
    2. מעבירים את אובייקט Shape אל MaterialTheme.

      פרטים נוספים זמינים במאמר בנושא צורות.

  • אם באפליקציה שלכם נעשה שימוש בטיפוגרפיה בהתאמה אישית:

    1. בקטע הקוד של Compose, מגדירים אובייקט Typography כדי לשכפל את סגנונות הטקסט והגדרות הגופן של XML.
    2. מעבירים את אובייקט Typography אל MaterialTheme.

      לפרטים נוספים, אפשר לקרוא את המאמר בנושא טיפוגרפיה.

הרכבת תפקיד שם ה-XML
displayLarge TextAppearance.Material3.DisplayLarge
displayMedium TextAppearance.Material3.DisplayMedium
displaySmall TextAppearance.Material3.DisplaySmall
headlineLarge TextAppearance.Material3.HeadlineLarge
headlineMedium TextAppearance.Material3.HeadlineMedium
headlineSmall TextAppearance.Material3.HeadlineSmall
titleLarge TextAppearance.Material3.TitleLarge
titleMedium TextAppearance.Material3.TitleMedium
titleSmall TextAppearance.Material3.TitleSmall
bodyLarge TextAppearance.Material3.BodyLarge
bodyMedium TextAppearance.Material3.BodyMedium
bodySmall TextAppearance.Material3.BodySmall
labelLarge TextAppearance.Material3.LabelLarge
labelMedium TextAppearance.Material3.LabelMedium
labelSmall TextAppearance.Material3.LabelSmall

שלב 5: העברת סגנונות (styles.xml)

מערכת סגנונות ה-XML (styles.xml) מגדירה סגנונות ומראה של: ‫1. ווידג'טים, רכיבים, עיצובים לחלונות ולתיבות דו-שיח ‫2. טיפוגרפיה ‫3. עיצובים ושכבות-על ‫4. צורות

תצוגות ורכיבים ב-XML משלבים כמה מאפיינים כדי ליצור סגנון. הם מגדירים את הסגנונות שלהם מתוך styles.xml בשתי דרכים שונות: ‫1. הגדרה של style="@style/...‎" ישירות ובאופן מפורש בתצוגת ה-XML ‫2. הגדרת הסגנון באופן עקיף ומשתמע לרכיב כחלק מ-Theme גדול יותר (theme.xml)

אין סגנונות מקבילים ישירות ב-Compose. במקום זאת, הסגנונות מועברים כפרמטרים לרכיבי composable, מוגדרים ב-AppTheme או על ידי יצירת וריאציות של רכיבי composable שניתן לעשות בהם שימוש חוזר עם הסגנון המוגדר.

צריך לספק פונקציות נפרדות עם הערך @Composable ששמן נקבע לפי הסגנון ורכיב הבסיס, כדי לציין את ההבדל בסגנון ובמקרי השימוש של הרכיבים האלה.

  • תבנית: אם רכיב XML משתמש בסגנון מותאם אישית (לדוגמה, style="@style/MyPrimaryButton"), אל תנסו לשכפל את הסגנון בשורה. במקום זאת, מציעים ליצור קומפוננטה ספציפית.
  • דוגמה:
    • XML: <Button style="@style/MyPrimaryButton" ... />
    • כתיבת הודעה: MyPrimaryButton(onClick = { ... })
  • קבוצות נפוצות של מאפיינים: אם סגנון מגדיר משנים נפוצים (כמו padding + height), כדאי לחלץ אותם למאפיין הרחבה קריא או למשתנה Modifier משותף.

דוגמאות נפוצות

XML כתיבה
Theme.MaterialComponents.* MaterialTheme(colorScheme, typography, shapes) { }
TextAppearance.Material3.BodyMedium TextStyle(...) מוגדר ב-Typography(bodyMedium = ...)
ShapeAppearance.*.SmallComponent Shapes(small = RoundedCornerShape(X.dp))
Widget.MaterialComponents.Button Button(colors = ButtonDefaults.buttonColors(...))
Widget.MaterialComponents.CardView Card(shape=..., elevation=..., colors=...)
Widget.*.TextInputLayout.OutlinedBox OutlinedTextField(colors = OutlinedTextFieldDefaults.colors(...))
Widget.*.Chip.Filter FilterChip(colors = FilterChipDefaults.filterChipColors(...))
Widget.*.Toolbar.Primary TopAppBar(colors = TopAppBarDefaults.topAppBarColors(...))
Widget.*.FloatingActionButton FloatingActionButton(containerColor = ...)
backgroundTint containerColor בעוד ComponentDefaults.ComponentColors()
android:textColor contentColor בעוד ComponentDefaults.ComponentColors()
cornerRadius shape = RoundedCornerShape(X.dp)
android:elevation elevation = ComponentDefaults.elevation(defaultElevation = X.dp)
android:padding contentPadding = PaddingValues(...) או Modifier.padding()
android:minHeight Modifier.heightIn(min = X.dp)
strokeColor + strokeWidth border = BorderStroke(width, color)
android:textSize fontSize = X.sp בעוד TextStyle

שלב 6: אימות העברת העיצוב

תמיד צריך להשתמש בערכי העיצוב הקיימים מתוך עיצוב ה-XML המקורי כמקור האמת לעיצוב Material החדש ב-Compose. אסור להמציא ערכי עיצוב חדשים במהלך ההעברה, כדי לשמור על עקביות המותג ולהימנע מרגרסיות חזותיות.

מוודאים שכל הערכים החדשים של ערכת הנושא של Compose זהים לערכי ה-XML הקיימים. אל תקודדו ערכים שהועברו.