בדף הזה מופיעה סקירה כללית על השכבות הארכיטקטוניות שמרכיבות את Jetpack Compose, ועל העקרונות המרכזיים שעליהם מבוסס העיצוב הזה.
Jetpack Compose הוא לא פרויקט מונוליטי אחד, אלא מורכב מכמה מודולים שמרכיבים יחד סטאק שלם. הבנת המודולים השונים שמרכיבים את Jetpack Compose מאפשרת לכם:
- שימוש ברמת ההפשטה המתאימה כדי ליצור את האפליקציה או הספרייה
- להבין מתי אפשר "לרדת" לרמה נמוכה יותר כדי לקבל יותר שליטה או התאמה אישית
- צמצום יחסי התלות
שכבות
השכבות העיקריות של Jetpack Compose הן:
איור 1. השכבות העיקריות של Jetpack Compose.
כל שכבה בנויה על השכבות שמתחתיה, ומשלבת פונקציונליות כדי ליצור רכיבים ברמה גבוהה יותר. כל שכבה מתבססת על ממשקי API ציבוריים של השכבות שמתחתיה כדי לאמת את גבולות המודול, ומאפשרת לכם להחליף כל שכבה לפי הצורך. בואו נבחן את השכבות האלה מלמטה למעלה.
- זמן ריצה
- המודול הזה מספק את העקרונות הבסיסיים של סביבת זמן הריצה של Compose, כמו
remember,mutableStateOf, ההערה@Composableו-SideEffect. אם אתם צריכים רק את יכולות ניהול העץ של Compose, ולא את ממשק המשתמש שלו, כדאי לשקול לבנות ישירות על השכבה הזו. - ממשק משתמש
- שכבת ממשק המשתמש מורכבת מכמה מודולים (
ui-text,ui-graphics,ui-tooling, וכו'). המודולים האלה מיישמים את היסודות של ערכת הכלים של ממשק המשתמש, כמוLayoutNode,Modifier, פונקציות טיפול בקלט, פריסות בהתאמה אישית וציור. אם אתם צריכים רק מושגים בסיסיים של ערכת כלים לממשק משתמש, כדאי לכם לשקול לבנות על השכבה הזו. - Foundation
- המודול הזה מספק אבני בניין שאינן תלויות במערכת העיצוב של ממשק המשתמש של Compose, כמו
Rowו-Column,LazyColumn, זיהוי של תנועות מסוימות וכו'. אפשר להשתמש בשכבת הבסיס כדי ליצור מערכת עיצוב משלכם. - חומר
- המודול הזה מספק הטמעה של מערכת Material Design לממשק המשתמש של Compose, ומספק מערכת של עיצובים, רכיבים מעוצבים, אינדיקציות של אפקט אדווה וסמלים. כשמשתמשים ב-Material Design באפליקציה, כדאי להוסיף עוד שכבות מעל השכבה הזו.
עקרונות העיצוב
אחד העקרונות המנחים של Jetpack Compose הוא לספק פונקציונליות קטנה וממוקדת שאפשר להרכיב (או ליצור) ביחד, במקום כמה רכיבים מונוליטיים. לגישה הזו יש כמה יתרונות.
שליטה
רכיבים ברמה גבוהה יותר נוטים לעשות יותר בשבילכם, אבל מגבילים את מידת השליטה הישירה שיש לכם. אם אתם צריכים יותר שליטה, אתם יכולים "לרדת" ולהשתמש ברכיב ברמה נמוכה יותר.
לדוגמה, אם רוצים להוסיף אנימציה לצבע של רכיב, אפשר להשתמש ב-API של animateColorAsState:
val color = animateColorAsState(if (condition) Color.Green else Color.Red)
עם זאת, אם אתם צריכים שהרכיב תמיד יתחיל בצבע אפור, אי אפשר לעשות את זה באמצעות ה-API הזה. במקום זאת, אפשר להשתמש ב-API ברמה נמוכה יותר, Animatable:
val color = remember { Animatable(Color.Gray) } LaunchedEffect(condition) { color.animateTo(if (condition) Color.Green else Color.Red) }
ה-API ברמה הגבוהה יותר, animateColorAsState, מבוסס על ה-API ברמה הנמוכה יותר, Animatable. השימוש ב-API ברמה הנמוכה יותר מורכב יותר, אבל מאפשר יותר שליטה. בחרו את רמת ההפשטה שהכי מתאימה לצרכים שלכם.
התאמה אישית
הרכבה של רכיבים ברמה גבוהה יותר מאבני בניין קטנות יותר מקלה מאוד על התאמה אישית של רכיבים, אם צריך. לדוגמה, נבחן את ההטמעה של Button שסופקה על ידי שכבת Material:
@Composable fun Button( // … content: @Composable RowScope.() -> Unit ) { Surface(/* … */) { CompositionLocalProvider(/* … */) { // set LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { Row( // … content = content ) } } } }
Button מורכב מ-4 רכיבים:
חומר
Surfaceשמספק את הרקע, הצורה, הטיפול בקליקים וכו'.
CompositionLocalProviderשמשנה את ערך האלפא של התוכן כשהלחצן מופעל או מושבת.ProvideTextStyleמגדיר את סגנון ברירת המחדל של הטקסט
Rowמספק את מדיניות הפריסה שמוגדרת כברירת מחדל לתוכן של הלחצן
השמטנו כמה פרמטרים והערות כדי שהמבנה יהיה ברור יותר, אבל הרכיב כולו מכיל רק כ-40 שורות קוד כי הוא פשוט מרכיב את 4 הרכיבים האלה כדי להטמיע את הכפתור. רכיבים כמו Button מציגים פרמטרים מסוימים, כדי לאפשר התאמות אישיות נפוצות בלי להציף את המשתמשים בפרמטרים שיקשו על השימוש ברכיב. לדוגמה, רכיבי Material מציעים התאמות אישיות שצוינו במערכת Material Design, כך שקל לפעול לפי העקרונות של Material Design.
אבל אם אתם רוצים לבצע התאמה אישית מעבר לפרמטרים של הרכיב, אתם יכולים "לרדת" רמה אחת ולפצל רכיב. לדוגמה, ב-Material Design מצוין שלכפתורים צריך להיות רקע בצבע אחיד. אם אתם צריכים רקע עם מעבר צבעים, האפשרות הזו לא נתמכת בפרמטרים של Button. במקרה כזה, אתם יכולים להשתמש בהטמעה של Material Button כקובץ עזר ולבנות רכיב משלכם:
@Composable fun GradientButton( // … background: List<Color>, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background( Brush.horizontalGradient(background) ) ) { CompositionLocalProvider(/* … */) { // set material LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { content() } } } }
ההטמעה שלמעלה ממשיכה להשתמש ברכיבים משכבת Material, כמו המושגים של Material לגבי אלפא של התוכן הנוכחי וסגנון הטקסט הנוכחי. עם זאת, הוא מחליף את החומר Surface ב-Row ומעצב אותו כדי להשיג את המראה הרצוי.
אם אתם לא רוצים להשתמש בכלל בקונספטים של Material, למשל אם אתם בונים מערכת עיצוב מותאמת אישית משלכם, אתם יכולים להשתמש רק ברכיבים של שכבת הבסיס:
@Composable fun BespokeButton( // … backgroundColor: Color, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background(backgroundColor) ) { // No Material components used content() } }
ב-Jetpack Compose, השמות הפשוטים ביותר שמורים לרכיבים ברמה הגבוהה ביותר. לדוגמה,
androidx.compose.material.Text
מבוסס על
androidx.compose.foundation.text.BasicText.
כך תוכלו לספק הטמעה משלכם עם השם הכי קל לגילוי, אם תרצו להחליף רמות גבוהות יותר.
בחירת ההפשטה המתאימה
הפילוסופיה של Compose לגבי בניית רכיבים בשכבות שניתן לעשות בהם שימוש חוזר, אומרת שלא תמיד צריך להגיע לאבני הבניין ברמה הנמוכה יותר. הרבה רכיבים ברמה גבוהה יותר לא רק מציעים יותר פונקציונליות, אלא גם מיישמים שיטות מומלצות כמו תמיכה בנגישות.
לדוגמה, אם אתם רוצים להוסיף תמיכה בתנועות לרכיב בהתאמה אישית, אתם יכולים ליצור אותו מאפס באמצעות Modifier.pointerInput, אבל יש רכיבים אחרים ברמה גבוהה יותר שמבוססים על זה, ויכול להיות שהם יציעו נקודת התחלה טובה יותר, למשל Modifier.draggable, Modifier.scrollable או Modifier.swipeable.
ככלל, עדיף לבנות על הרכיב ברמה הגבוהה ביותר שמציע את הפונקציונליות שאתם צריכים כדי ליהנות מהשיטות המומלצות שהם כוללים.
מידע נוסף
בדוגמה של Jetsnack מוסבר איך ליצור מערכת עיצוב בהתאמה אישית.
מומלץ בשבילך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- Kotlin ל-Jetpack Compose
- רשימות ורשתות
- תופעות לוואי בפיתוח נייטיב