המבנה של עיצוב בנייטיב

עיצובים ב-Jetpack Compose מורכבים מכמה מבנים ברמה נמוכה יותר ומממשקי API קשורים. אפשר לראות אותם בקוד המקור של MaterialTheme, וגם להחיל אותם במערכות עיצוב בהתאמה אישית.

מחלקות של מערכת העיצוב

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

לדוגמה, MaterialTheme כולל את ColorScheme (מערכת צבעים), Typography (מערכת טיפוגרפיה) ו- Shapes (מערכת צורות).

@Immutable
data class ColorSystem(
    val color: Color,
    val gradient: List<Color>
    /* ... */
)

@Immutable
data class TypographySystem(
    val fontFamily: FontFamily,
    val textStyle: TextStyle
)
/* ... */

@Immutable
data class CustomSystem(
    val value1: Int,
    val value2: String
    /* ... */
)

/* ... */

Theme system composition locals

מחלקות של מערכת העיצובים מסופקות באופן משתמע לעץ הקומפוזיציה כמופעים של CompositionLocal. כך אפשר להפנות באופן סטטי לערכים של עיצובים בפונקציות קומפוזביליות.

מידע נוסף על CompositionLocal זמין במדריך בנושא נתונים ברמה המקומית באמצעות CompositionLocal.

val LocalColorSystem = staticCompositionLocalOf {
    ColorSystem(
        color = Color.Unspecified,
        gradient = emptyList()
    )
}

val LocalTypographySystem = staticCompositionLocalOf {
    TypographySystem(
        fontFamily = FontFamily.Default,
        textStyle = TextStyle.Default
    )
}

val LocalCustomSystem = staticCompositionLocalOf {
    CustomSystem(
        value1 = 0,
        value2 = ""
    )
}

/* ... */

פונקציית עיצוב

פונקציית העיצוב היא נקודת הכניסה וה-API הראשי. הוא יוצר מופעים של CompositionLocal של מערכת העיצוב – באמצעות ערכים אמיתיים וכל לוגיקה שנדרשת – שמועברים לעץ הקומפוזיציה באמצעות CompositionLocalProvider. הפרמטר content מאפשר לפונקציות ה-composable המקוננות לגשת לערכי העיצוב שרלוונטיים להיררכיה.

@Composable
fun Theme(
    /* ... */
    content: @Composable () -> Unit
) {
    val colorSystem = ColorSystem(
        color = Color(0xFF3DDC84),
        gradient = listOf(Color.White, Color(0xFFD7EFFF))
    )
    val typographySystem = TypographySystem(
        fontFamily = FontFamily.Monospace,
        textStyle = TextStyle(fontSize = 18.sp)
    )
    val customSystem = CustomSystem(
        value1 = 1000,
        value2 = "Custom system"
    )
    /* ... */
    CompositionLocalProvider(
        LocalColorSystem provides colorSystem,
        LocalTypographySystem provides typographySystem,
        LocalCustomSystem provides customSystem,
        /* ... */
        content = content
    )
}

אובייקט העיצוב

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

// Use with eg. Theme.colorSystem.color
object Theme {
    val colorSystem: ColorSystem
        @Composable
        get() = LocalColorSystem.current
    val typographySystem: TypographySystem
        @Composable
        get() = LocalTypographySystem.current
    val customSystem: CustomSystem
        @Composable
        get() = LocalCustomSystem.current
    /* ... */
}