סגנונות ועיצובים ב-Android מאפשרים לכם להפריד בין פרטי העיצוב של האפליקציה לבין המבנה וההתנהגות של ממשק המשתמש, בדומה לגיליונות סגנונות בעיצוב אתרים.
סגנון הוא אוסף של מאפיינים שמגדירים את המראה של View יחיד. סגנון יכול לציין מאפיינים כמו צבע הגופן, גודל הגופן, צבע הרקע ועוד.
עיצוב הוא אוסף של מאפיינים שמוחלים על אפליקציה, פעילות או היררכיית תצוגות שלמה, ולא רק על תצוגה בודדת. כשמחילים עיצוב, כל תצוגה באפליקציה או בפעילות מחילה את כל המאפיינים של העיצוב שהיא תומכת בהם. עיצובים יכולים גם להחיל סגנונות על רכיבים שאינם תצוגה, כמו שורת הסטטוס ורקע החלון.
הסגנונות והעיצובים מוגדרים בקובץ משאבים של סגנונות ב-res/values/, שבדרך כלל נקרא styles.xml.
איור 1. שני עיצובים שהוחלו על אותה פעילות:
Theme.AppCompat (משמאל) ו-Theme.AppCompat.Light (מימין).
עיצובים לעומת סגנונות
יש הרבה דמיון בין עיצובים לסגנונות, אבל הם משמשים למטרות שונות. לעיצובים ולסגנונות יש מבנה בסיסי זהה – צמד מפתח/ערך שממפה מאפיינים למשאבים.
סגנון מציין מאפיינים של סוג מסוים של תצוגה. לדוגמה, סגנון אחד יכול לציין את המאפיינים של כפתור. כל מאפיין שאתם מציינים בסגנון הוא מאפיין שאפשר להגדיר בקובץ הפריסה. כשמחלצים את כל המאפיינים לסגנון, קל להשתמש בהם ולתחזק אותם בכמה ווידג'טים.
עיצוב מגדיר אוסף של משאבים עם שמות שאפשר להפנות אליהם באמצעות סגנונות, פריסות, ווידג'טים וכו'. עיצובים מקצים שמות סמנטיים, כמו colorPrimary, למשאבים של Android.
הסגנונות והעיצובים נועדו לעבוד ביחד. לדוגמה, יכול להיות שסגנון מסוים מגדיר שחלק אחד של כפתור הוא colorPrimary וחלק אחר הוא colorSecondary. ההגדרות בפועל של הצבעים האלה מופיעות בעיצוב. כשהמכשיר עובר למצב לילה, האפליקציה יכולה לעבור מהעיצוב הבהיר לעיצוב הכהה, ולשנות את הערכים של כל שמות המשאבים האלה. לא צריך לשנות את הסגנונות, כי הסגנונות משתמשים בשמות הסמנטיים ולא בהגדרות צבע ספציפיות.
בפוסט Android styling: themes vs styles בבלוג מוסבר איך עיצובים וסגנונות פועלים יחד.
יצירה והחלה של סגנון
כדי ליצור סגנון חדש, פותחים את הקובץ res/values/styles.xml של הפרויקט. כדי ליצור סגנון:
- מוסיפים רכיב
<style>עם שם שמזהה את הסגנון באופן ייחודי. - מוסיפים רכיב
<item>לכל מאפיין סגנון שרוצים להגדיר. הערך שלnameבכל פריט מציין מאפיין שמשמש כמאפיין XML בפריסה. הערך ברכיב<item>הוא הערך של המאפיין הזה.
לדוגמה, נניח שאתם מגדירים את הסגנון הבא:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="GreenText" parent="TextAppearance.AppCompat"> <item name="android:textColor">#00FF00</item> </style> </resources>
כדי להחיל את הסגנון על תצוגה:
<TextView style="@style/GreenText" ... />
כל מאפיין שצוין בסגנון מוחל על התצוגה הזו, אם התצוגה מקבלת אותו. התצוגה מתעלמת מכל מאפיין שלא נתמך בה.
עם זאת, במקום להחיל סגנון על תצוגות ספציפיות, בדרך כלל מחילים סגנונות כעיצוב על כל האפליקציה, הפעילות או אוסף התצוגות, כפי שמתואר בקטע אחר במדריך הזה.
הרחבה והתאמה אישית של סגנון
כשיוצרים סגנונות משלכם, תמיד צריך להרחיב סגנון קיים מה-framework או מספריית התמיכה כדי לשמור על תאימות לסגנונות של ממשק המשתמש בפלטפורמה. כדי להרחיב סגנון, מציינים את הסגנון שרוצים להרחיב באמצעות המאפיין parent. אחר כך אפשר לשנות את מאפייני הסגנון שעברו בירושה ולהוסיף מאפיינים חדשים.
לדוגמה, אפשר לרשת את מראה הטקסט שמוגדר כברירת מחדל בפלטפורמת Android ולשנות אותו באופן הבא:
<style name="GreenText" parent="@android:style/TextAppearance"> <item name="android:textColor">#00FF00</item> </style>
עם זאת, תמיד צריך לרשת את סגנונות האפליקציה העיקריים מספריית התמיכה של Android. הסגנונות בספריית התמיכה מספקים תאימות על ידי אופטימיזציה של כל סגנון למאפייני ממשק המשתמש שזמינים בכל גרסה. לסגנונות של ספריית התמיכה יש בדרך כלל שם דומה לסגנון מהפלטפורמה, אבל עם AppCompat.
כדי לרשת סגנונות מספרייה או מהפרויקט שלכם, צריך להצהיר על שם הסגנון של ההורה בלי החלק @android:style/ שמוצג בדוגמה הקודמת. לדוגמה, בדוגמה הבאה, סגנונות המראה של הטקסט עוברים בירושה מספריית התמיכה:
<style name="GreenText" parent="TextAppearance.AppCompat"> <item name="android:textColor">#00FF00</item> </style>
אפשר גם לרשת סגנונות – מלבד אלה מהפלטפורמה – על ידי הרחבת שם הסגנון באמצעות סימון נקודה, במקום להשתמש במאפיין parent. כלומר, מוסיפים לשם הסגנון את שם הסגנון שרוצים לרשת, וביניהם נקודה. בדרך כלל עושים את זה רק כשמרחיבים את הסגנונות שלכם, ולא סגנונות מספריות אחרות. לדוגמה, הסגנון הבא יורש את כל הסגנונות מה-GreenText בדוגמה הקודמת, ואז מגדיל את גודל הטקסט:
<style name="GreenText.Large"> <item name="android:textSize">22dp</item> </style>
אפשר להמשיך לרשת סגנונות בצורה כזו כמה פעמים שרוצים, על ידי שרשור של שמות נוספים.
כדי לראות אילו מאפיינים אפשר להצהיר באמצעות תג <item>, עיינו בטבלה "מאפייני XML" בחומרי העזר השונים של המחלקות. כל התצוגות תומכות במאפייני XML מהמחלקה הבסיסית View, ובתצוגות רבות נוספים מאפיינים מיוחדים משלהן. לדוגמה, מאפייני ה-XML של TextView כוללים את המאפיין android:inputType, שאפשר להחיל על תצוגת טקסט שמקבלת קלט, כמו ווידג'ט EditText.
החלת סגנון כעיצוב
אפשר ליצור עיצוב באותו אופן שבו יוצרים סגנונות. ההבדל הוא באופן ההחלה: במקום להחיל סגנון עם המאפיין style בתצוגה, מחילים עיצוב עם המאפיין android:theme בתג <application> או בתג <activity> בקובץ AndroidManifest.xml.
לדוגמה, כך מחילים את העיצוב הכהה של Material Design מספריית התמיכה של Android על כל האפליקציה:
<manifest ... > <application android:theme="@style/Theme.AppCompat" ... > </application> </manifest>
כך מחילים את העיצוב "בהיר" על פעילות אחת בלבד:
<manifest ... > <application ... > <activity android:theme="@style/Theme.AppCompat.Light" ... > </activity> </application> </manifest>
כל תצוגה באפליקציה או בפעילות מחילה את הסגנונות שהיא תומכת בהם מתוך הסגנונות שמוגדרים בעיצוב הנתון. אם תצוגה תומכת רק בחלק מהמאפיינים שהוגדרו בסגנון, היא תחיל רק את המאפיינים האלה ותתעלם מהמאפיינים שהיא לא תומכת בהם.
החל מ-Android 5.0 (רמת API 21) וספריית התמיכה של Android בגרסה 22.1, אפשר גם לציין את המאפיין android:theme לתצוגה בקובץ הפריסה. הפעולה הזו משנה את העיצוב של התצוגה הזו ושל כל תצוגות הצאצא, וזה שימושי לשינוי לוחות הצבעים של העיצוב בחלק ספציפי של הממשק.
בדוגמאות הקודמות אפשר לראות איך להחיל עיצוב כמו Theme.AppCompat שמסופק על ידי ספריית התמיכה של Android. עם זאת, בדרך כלל כדאי להתאים אישית את העיצוב כך שיתאים למותג של האפליקציה. הדרך הכי טובה לעשות את זה היא להרחיב את הסגנונות האלה מספריית התמיכה ולשנות חלק מהמאפיינים, כמו שמתואר בקטע הבא.
היררכיית הסגנונות
ב-Android יש מגוון דרכים להגדיר מאפיינים באפליקציה ל-Android. לדוגמה, אפשר להגדיר מאפיינים ישירות בפריסה, להחיל סגנון על תצוגה, להחיל עיצוב על פריסה ואפילו להגדיר מאפיינים באופן פרוגרמטי.
כשבוחרים את הסגנון של האפליקציה, חשוב לשים לב להיררכיית הסגנונות של Android. באופן כללי, כדאי להשתמש בעיצובים ובסגנונות כמה שיותר כדי לשמור על עקביות. אם תציינו את אותם מאפיינים בכמה מקומות, הרשימה הבאה תקבע אילו מאפיינים יחולו בסופו של דבר. הרשימה מסודרת לפי סדר העדיפות, מהגבוהה לנמוכה.
- החלת סגנון ברמת התו או הפסקה באמצעות טווחי טקסט על מחלקות שנגזרות מ-
TextView. - החלת מאפיינים באופן פרוגרמטי.
- החלת מאפיינים ספציפיים ישירות על תצוגה.
- החלת סגנון על תצוגה.
- עיצוב ברירת מחדל.
- החלת עיצוב על אוסף של תצוגות, על פעילות או על האפליקציה כולה.
- החלת סגנון ספציפי לתצוגה, כמו הגדרת
TextAppearanceב-TextView.
איור 2. העיצוב של span מבטל את העיצוב של textAppearance.
TextAppearance
אחת המגבלות של סגנונות היא שאפשר להחיל רק סגנון אחד על View. עם זאת, ב-TextView אפשר גם לציין מאפיין TextAppearance שפועל באופן דומה לסגנון, כמו בדוגמה הבאה:
<TextView ... android:textAppearance="@android:style/TextAppearance.Material.Headline" android:text="This text is styled via textAppearance!" />
התג TextAppearance מאפשר להגדיר סגנון ספציפי לטקסט, ולהשאיר את הסגנון של View זמין לשימושים אחרים. עם זאת, שימו לב שאם אתם מגדירים מאפייני טקסט ישירות ב-View או בסגנון, הערכים האלה מבטלים את הערכים של TextAppearance.
TextAppearance תומך בקבוצת משנה של מאפייני סגנון ש-TextView מציע. לרשימת המאפיינים המלאה, ראו TextAppearance.
מאפיינים נפוצים של TextView שלא נכללים הם
lineHeight[Multiplier|Extra],
lines,
breakStrategy ו-
hyphenationFrequency.
TextAppearance פועל ברמת התו ולא ברמת הפסקה, ולכן אין תמיכה במאפיינים שמשפיעים על כל הפריסה.
התאמה אישית של עיצוב ברירת המחדל
כשיוצרים פרויקט באמצעות Android Studio, כברירת מחדל המערכת מחילה על האפליקציה עיצוב Material Design, כפי שמוגדר בקובץ styles.xml של הפרויקט. הסגנון AppTheme הזה מרחיב עיצוב מספריית התמיכה וכולל שינויים של מאפייני צבע שמשמשים רכיבים מרכזיים בממשק המשתמש, כמו סרגל האפליקציה וכפתור הפעולה הצף (FAB), אם משתמשים בהם. כך תוכלו להתאים אישית במהירות את עיצוב הצבעים של האפליקציה על ידי עדכון הצבעים שסופקו.
לדוגמה, קובץ styles.xml נראה כך:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style>
ערכי הסגנון הם למעשה הפניות למשאבי צבע אחרים, שמוגדרים בקובץ res/values/colors.xml של הפרויקט. זה הקובץ שצריך לערוך כדי לשנות את הצבעים.
כדי לשפר את חוויית המשתמש באמצעות צבעים דינמיים וצבעים נוספים בהתאמה אישית, אפשר לעיין בסקירה הכללית של הצבעים ב-Material Design.
אחרי שבוחרים את הצבעים, מעדכנים את הערכים ב-res/values/colors.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- Color for the app bar and other primary UI elements. --> <color name="colorPrimary">#3F51B5</color> <!-- A darker variant of the primary color, used for the status bar (on Android 5.0+) and contextual app bars. --> <color name="colorPrimaryDark">#303F9F</color> <!-- a secondary color for controls like checkboxes and text fields. --> <color name="colorAccent">#FF4081</color> </resources>
אחר כך אפשר לשנות את הסגנונות האחרים שרוצים. לדוגמה, אפשר לשנות את צבע הרקע של הפעילות באופן הבא:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ... <item name="android:windowBackground">@color/activityBackground</item> </style>
רשימה של מאפיינים שאפשר להשתמש בהם בעיצוב מופיעה בטבלת המאפיינים בכתובת R.styleable.Theme. כשמוסיפים סגנונות לתצוגות בפריסה, אפשר גם למצוא מאפיינים בטבלה XML attributes בהפניות למחלקות של התצוגות. לדוגמה, כל התצוגות תומכות במאפייני XML מהמחלקה הבסיסית View.
רוב המאפיינים חלים על סוגים ספציפיים של תצוגות, וחלקם חלים על כל התצוגות. עם זאת, חלק ממאפייני העיצוב שמפורטים ב-R.styleable.Theme חלים על חלון הפעילות, ולא על התצוגות בפריסה. לדוגמה, windowBackground משנה את הרקע של החלון ו-windowEnterTransition מגדיר אנימציית מעבר שתופעל כשהפעילות תתחיל. פרטים נוספים זמינים במאמר איך מתחילים פעילות באמצעות אנימציה.
ספריית התמיכה של Android מספקת גם מאפיינים אחרים שבהם אפשר להשתמש כדי להתאים אישית את העיצוב שמרחיב את Theme.AppCompat, כמו המאפיין colorPrimary שמוצג בדוגמה הקודמת. הדרך הכי טובה לראות אותם היא בקובץ attrs.xml של הספרייה.
בספריית התמיכה יש גם עיצובים שונים שאפשר להרחיב במקום אלה שמוצגים בדוגמה הקודמת. המקום הכי טוב לראות את העיצובים הזמינים הוא הקובץ themes.xml של הספרייה.
הוספת סגנונות ספציפיים לגרסה
אם גרסה חדשה של Android מוסיפה מאפייני עיצוב שאתם רוצים להשתמש בהם, אתם יכולים להוסיף אותם לעיצוב שלכם ועדיין לשמור על תאימות לגרסאות ישנות. כל מה שצריך זה קובץ styles.xml נוסף שנשמר בספרייה values שכוללת את מזהה גרסת המשאב:
res/values/styles.xml # themes for all versions res/values-v21/styles.xml # themes for API level 21+ only
הסגנונות בקובץ values/styles.xml זמינים לכל הגרסאות, ולכן העיצובים ב-values-v21/styles.xml יכולים לרשת אותם. כך אפשר להימנע משכפול סגנונות: מתחילים עם עיצוב "בסיסי" ואז מרחיבים אותו בסגנונות הספציפיים לגרסה.
לדוגמה, כדי להצהיר על מעברי חלונות ב-Android 5.0 (רמת API 21) ומעלה, צריך להשתמש במאפיינים חדשים. לכן, העיצוב הבסיסי ב-res/values/styles.xml יכול להיראות כך:
<resources> <!-- Base set of styles that apply to all versions. --> <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/primaryColor</item> <item name="colorPrimaryDark">@color/primaryTextColor</item> <item name="colorAccent">@color/secondaryColor</item> </style> <!-- Declare the theme name that's actually applied in the manifest file. --> <style name="AppTheme" parent="BaseAppTheme" /> </resources>
לאחר מכן, מוסיפים את הסגנונות הספציפיים לגרסה ב-res/values-v21/styles.xml, באופן הבא:
<resources> <!-- extend the base theme to add styles available only with API level 21+ --> <style name="AppTheme" parent="BaseAppTheme"> <item name="android:windowActivityTransitions">true</item> <item name="android:windowEnterTransition">@android:transition/slide_right</item> <item name="android:windowExitTransition">@android:transition/slide_left</item> </style> </resources>
עכשיו אפשר להחיל את AppTheme בקובץ המניפסט, והמערכת בוחרת את הסגנונות שזמינים לכל גרסת מערכת.
למידע נוסף על שימוש במשאבים חלופיים למכשירים שונים, ראו מתן משאבים חלופיים.
התאמה אישית של סגנונות הווידג'טים
לכל ווידג'ט ב-framework ובספריית התמיכה יש סגנון ברירת מחדל. לדוגמה, כשמעצבים את האפליקציה באמצעות עיצוב מספריית התמיכה, מופע של Button מעוצב באמצעות הסגנון Widget.AppCompat.Button. אם רוצים להחיל סגנון ווידג'ט אחר על כפתור, אפשר לעשות את זה באמצעות המאפיין style בקובץ הפריסה. לדוגמה, הקוד הבא מחיל את סגנון הלחצן ללא גבולות של הספרייה:
<Button style="@style/Widget.AppCompat.Button.Borderless" ... />
אם רוצים להחיל את הסגנון הזה על כל הכפתורים, אפשר להצהיר עליו ב-buttonStyle של העיצוב באופן הבא:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="buttonStyle">@style/Widget.AppCompat.Button.Borderless</item> ... </style>
אפשר גם להרחיב סגנונות של ווידג'טים, בדיוק כמו הרחבה של כל סגנון אחר, ואז להחיל את הסגנון המותאם אישית של הווידג'ט בפריסה או בעיצוב.
מקורות מידע נוספים
מידע נוסף על עיצובים וסגנונות זמין במקורות המידע הבאים:
פוסטים בבלוגים
- עיצוב ב-Android: עיצובים לעומת סגנונות
- עיצוב ב-Android: מאפייני עיצוב נפוצים
- עיצוב ב-Android: עדיף להשתמש במאפייני עיצוב