העברת עיצובים ב-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 והמשאבים שנדרשים לעיצוב: סכימות צבעים בהיר וכהה, מזהים, עיצובים, צורות, מידות, טיפוגרפיה, סגנונות וקבצים רלוונטיים אחרים.

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

שלב 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 – במקום זאת, הסגנונות מועברים כ: פרמטרים לרכיבים הניתנים להרכבה, מוגדרים ב-AppTheme או על ידי יצירת וריאציות של רכיבים ניתנים להרכבה, שניתן לעשות בהם שימוש חוזר, עם הסגנון המוגדר.

צריך לספק פונקציות נפרדות מסוג @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. אל תקודדו ערכים שהועברו.