מיפוי רכיבים לקוד קיים

מפתחים יכולים להתאים אישית את תהליך יצירת הקוד על ידי מתן מיפוי בין חבילת ממשק משתמש לבין רכיב קוד קיים במקום הקוד שנוצר. האפשרות הזו שימושית כשלהטמעה הקיימת יש תכונות שלא ניתן להשיג באמצעות הקוד שנוצר, כמו אנימציה או התנהגות מורכבת (למשל תפריט נפתח).

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

תרשים סקירה כללית של רכיבים ממופים

לדוגמה:

ב-Figma, מעצב יוצר רכיב Card שמכיל מופע של רכיב Play Bar, מעטפת את שני הרכיבים ושולח אותם למפתח.

כשהמפתח מייבא את חבילות ממשק המשתמש מ-Figma, נוצרות שתי ספריות ב-ui-packages: card ו-play_bar. כשהם יוצרים את הפרויקט, נוצרות שתי פונקציות שאפשר להרכיב: Card ו-PlayBar. בדרך כלל, מכיוון ש-Card מכיל מופע של Play Bar ב-Figma, בקוד הפונקציה הניתנת לקיבוץ Card מכילה קריאה לפונקציה הניתנת לקיבוץ PlayBar.

עם זאת, המעצב והמפתח רוצים להשתמש ב-Card במקום זאת ברכיב מורכב קיים, MyExistingPlaybar, שיש לו פונקציונליות שקשה לתאר ב-Figma. לכן המפתח מוסיף קובץ מיפוי שנקרא play_bar.json שממפה את חבילת ממשק המשתמש play_bar אל MyExistingPlaybar:

{
    "target": "MyExistingPlaybar",
    "package": "com.example.myApp"
}

עכשיו, כשהמפתח יוצר את הפרויקט, Card קורא ל-MyExistingPlaybar במקום ל-PlayBar. חשוב לזכור של-MyExistingPlaybar צריכים להיות אותם פרמטרים כמו ל-PlayBar (אבל יכולים להיות כמה הבדלים, כפי שמתואר בקטע הוראות נוספות בהמשך).

קובץ מיפוי

בפרויקטים ב-Android Studio, קובצי המיפוי מתווספים בתיקייה ui-package-resources/mappings לצד התיקייה ui-packages. Relay מחפש קובצי מיפוי במהלך ה-build.

קובץ מיפוי בתצוגת הפרויקט

יצירת קובץ מיפוי

Relay יכול ליצור קובץ מיפוי לכל חבילת ממשק משתמש שיובאה. מבצעים את הפעולות הבאות:

  1. לוחצים לחיצה ימנית על תיקיית החבילה או על קובץ כלשהו בתיקיית היעד ui-package. בוחרים באפשרות יצירת קובץ מיפוי.

    יצירת קובץ מיפוי

הנחיה

  2. מגדירים את האפשרויות הבאות בתיבת הדו-שיח:

    תיבת דו-שיח ליצירת קובצי מיפוי

    • מיקום הקובץ: מגדיר את המיקום של קובץ המיפוי שנוצר.

    • Target composable: מגדיר את ה-composable המותאם אישית שמשמש במקום ה-composable שנוצר. תוכלו להשתמש ב-composable קיים או ליצור אחד חדש מתיבת הדו-שיח. יצירת רכיב חדש יוצרת רכיב עם אותם פרמטרים שהוגדרו בחבילת ממשק המשתמש.

    • קובץ שנוצר: מגדיר את האפשרויות generateImplementation ו-generatePreview בקובץ המיפוי. פרטים נוספים זמינים בקטע מיפוי תוכן של קובץ בהמשך.
  3. לוחצים על Generate mapping file. ייווצר קובץ מיפוי חדש בתיקייה ui-package-resources/mapping עם ההגדרות שצוינו.

אפשר גם לפתוח את תיבת הדו-שיח Generate mapping file בממשק המשתמש של מודול החבילה Relay באופן הבא:

  1. לוחצים על קובץ כלשהו של חבילת ממשק משתמש בתיקיית היעד ui-package.

  2. אם חלון הכלי של Relay לא נפתח באופן אוטומטי, לוחצים על סמל Relay כדי לפתוח את החלון.

  3. לוחצים על הלחצן Generate mapping file (יצירת קובץ מיפוי) בקטע Package Options (אפשרויות החבילה).

    יצירת קובץ מיפוי

הנחיה

שם קובץ המיפוי

השם של קובץ המיפוי צריך להיות זהה לשם התיקייה של חבילת ממשק המשתמש של הרכיב שהוא מחליף. כך, play_bar.json ממפה את חבילת ממשק המשתמש בתיקייה ui-packages/mappings לרכיב קוד קיים.

מיפוי תוכן הקובץ

קובץ המיפוי מכיל את המאפיינים הבאים:

  • target: (חובה) השם של הפונקציה המותאמת אישית שאפשר ליצור ממנה רכיבים. כברירת מחדל, זהו השם של הפונקציה שנוצרה על ידי הקוד שנוצר.

    "target" : "CustomComposableName"
    
  • package: (חובה) שם החבילה שבה נמצא הרכיב המותאם אישית. כברירת מחדל, זוהי החבילה של הפונקציה שנוצרה על ידי הקוד שנוצר.

    "package" : "com.example.podcastapp.ui.components"
    
  • generateImplementation: (אופציונלי) true או false. אם הערך הוא True, עדיין תתבצע הטמעה של חבילת ממשק המשתמש הזו בקובץ הקוד שנוצר. אם הערך הוא false, ההטמעה לא נוצרת. כברירת מחדל, הערך הוא true.

    "generateImplementation" : true
    
  • generatePreviews: (אופציונלי) true או false. אם הערך הוא True, נוצרת תצוגה מקדימה של הרכיב המותאם אישית הממופה בקובץ הקוד שנוצר. אם הערך הוא false, לא נוצר קטע מקדים. כברירת מחדל, הערך הוא true.

    "generatePreviews" : true
    

וריאציות ממופה

אם לרכיב ב-Figma יש וריאציות, הרכיב הניתן לקישור שנוצר מכיל פרמטרים של enum שמקודדים את הווריאנט (כפי שמתואר במדריך טיפול באפשרויות עיצוב). אם רוצים למפות רכיב של Figma עם וריאציות לקוד קיים, צריך למפות אותו לרכיב מורכב (composable) עם אותם פרמטרים כמו הרכיב המורכב שנוצר. לדוגמה, לרכיב Figma שנקרא Chip עם וריאנט שהנכס שלו הוא ChipType, החתימה הניתנת ליצירה שנוצרה ל-Chip נראית כך:

@Composable
fun Chip(
    modifier: Modifier = Modifier,
    chipType: ChipType = ChipType.Red,
    chipText: String
) { ... }

אם רוצים שהרכיב של Chip Figma ימופה ל-composable קיים של MyChip, לחתימה של MyChip צריך להיות אותו חתימה כמו לחתימה של ה-composable שנוצר (בהנחה שלא צוינו הוראות נוספות). מבחינה מושגית, המשמעות היא שרכיב הקוד הקיים יכול לתמוך באותן וריאציות עיצוב כמו רכיב Figma.

הוראות נוספות

לדוגמה, אם לחתימה של הפונקציה הניתנת לקיפול שאליה רוצים לטרגט יש את החתימה הבאה:

@Composable
fun MyChip(
    modifier: Modifier = Modifier,
    chipType: ChipType = ChipType.Red,
    description: String  // instead of chipText
) { ... }

אפשר להוסיף לקובץ המיפוי בלוק fieldMappings שמשפיע על אופן המיפוי של הפרמטרים. במקרה הזה, הוא מכיל מיפוי מהפרמטר chipText ב-Chip לפרמטר description ב-MyChip.

{
    "target": "MyChip",
    "package": "com.example.myApp",
    "fieldMappings": [
        {
            "type": "parameter",
            "source": "chipText",
            "target": "description"
        }
    ]
}

סוגי הבלוק fieldMappings כוללים:

  • parameter: מיפוי של שדה חבילת UI לפרמטר קוד.
    • source: שם הפרמטר כפי שצוין בחבילת ממשק המשתמש.
    • target: שם הפרמטר כפי שצוין ברכיב הקוד של היעד.
  • lambda: מיפוי של שדה חבילת UI ל-lambda של תוכן.
    • source: שם הפרמטר כפי שצוין בחבילת ממשק המשתמש.
    • target: שם הפרמטר כפי שצוין ברכיב הקוד של היעד.
  • modifier: מיפוי של שדה בחבילת UI ל-method של מַעְדִּג (modifier).

    • source: שם הפרמטר כפי שצוין בחבילת ממשק המשתמש.
    • method: שיטה באובייקט Modifier שצריך להפעיל בקוד שנוצר.
    • parameter: שם הפרמטר בתוך שיטת ה-Modifier שצוינה.
    • library: שם החבילה המורחב שצריך לייבא כדי לגשת לשיטה Modifier.
    • scope: אחד משני ערכים שמציינים את היקף המשתנה המשנה:
    • any: אפשר להשתמש במשתנה המשנה בכל היקף של מקלט.
    • relay: צריך להשתמש במשנה בהיקף הנמען של אובייקט RelayContainer של Relay.