סגנונות ועיצובים

רוצה לנסות את שיטת הכתיבה?
Jetpack Compose היא ערכת הכלים המומלצת לבניית ממשק משתמש ב-Android. כאן מוסבר איך עובדים איתם בנושא 'כתיבה'.

סגנונות ונושאים ב-Android מאפשרים לכם להפריד את פרטי עיצוב האפליקציה מהמבנה וההתנהגות של ממשק המשתמש, בדומה לגיליונות סגנונות בעיצוב אתרים.

סגנון הוא אוסף של מאפיינים שמציין את המראה של View. סגנון יכול לציין מאפיינים כמו צבע הגופן, גודל הגופן, צבע הרקע ועוד הרבה.

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

הסגנונות והעיצובים מוצהרים בהצהרה style resource file ב- res/values/, בדרך כלל בשם styles.xml.

איור 1. שני עיצובים שהוחלו על אותה פעילות: Theme.AppCompat (שמאל) ו-Theme.AppCompat.Light (ימין).

עיצובים לעומת סגנונות

לעיצובים ולסגנונות יש הרבה דמיון, אבל הם משמשים למטרות שונות. עיצובים ו לסגנונות יש מבנה בסיסי זהה – צמד מפתח/ערך שממפה את המאפיינים אל משאבים.

style מציין מאפיינים לסוג מסוים של תצוגה. לדוגמה, סגנון אחד יכול לציין את המאפיינים של הלחצן. כל מאפיין שמציינים בסגנון הוא מאפיין שאפשר להגדיר בו את קובץ הפריסה. חילוץ כל המאפיינים לסגנון מאפשר להשתמש בהם ולתחזק אותם בקלות בכמה ווידג'טים.

עיצוב מגדיר אוסף של משאבים עם שמות שאפשר להפנות אליהם באמצעות סגנונות, פריסות, ווידג'טים וכו'. נושאים מקצים שמות סמנטיים, כמו colorPrimary, למשאבים של Android.

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

למידע נוסף על האופן שבו עיצובים וסגנונות פועלים יחד, כדאי לקרוא את הפוסט בבלוג עיצוב ל-Android: עיצובים לעומת סגנונות.

יצירה והחלה של סגנון

כדי ליצור סגנון חדש, פותחים את הקובץ res/values/styles.xml של הפרויקט. עבור כדי ליצור כל סגנון, מבצעים את השלבים הבאים:

  1. מוסיפים רכיב <style> עם שם שמזהה את הסגנון באופן ייחודי.
  2. מוסיפים רכיב <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"
    ... />

כל מאפיין שצוין בסגנון חל על התצוגה הזו, אם התצוגה מקבלת אותו. התצוגה מתעלמת מכל המאפיינים שהיא לא מקבלת.

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

הרחבה והתאמה אישית של סגנון

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

לדוגמה, אפשר לרשת את מראה הטקסט שמוגדר כברירת מחדל בפלטפורמת Android ולשנות אותו באופן הבא:

<style name="GreenText" parent="@android:style/TextAppearance">
    <item name="android:textColor">#00FF00</item>
</style>

עם זאת, תמיד צריך לרשת את סגנונות האפליקציה העיקריים מספריית התמיכה ב-Android. הסגנונות ב-Support Library מספקים תאימות על ידי אופטימיזציה של כל סגנון למאפייני ממשק המשתמש שזמינים בכל גרסה. לסגנונות של ספריית התמיכה יש בדרך כלל שם דומה לסגנון של הפלטפורמה. אבל עם AppCompat כלול.

כדי לרשת סגנונות מספרייה או מפרויקט משלך, צריך להצהיר על שם הסגנון הראשי בלי החלק @android:style/ שמוצג בדוגמה הקודמת. לדוגמה, הדוגמה הבאה יורשת סגנונות של מראה טקסט מ-Support Library:

<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 כיתה, ולתצוגות רבות יש מאפיינים מיוחדים משלהן. לדוגמה, TextView מאפייני XML כוללים את 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 Support Library גרסה 22.1, ניתן גם לציין המאפיין android:theme לתצוגה בקובץ הפריסה. הפעולה הזו משנה את העיצוב של התצוגה הזו ושל כל תצוגת הצאצא שלה. היא שימושית לשינוי של לוחות הצבעים של העיצוב בחלק ספציפי בממשק.

הדוגמאות הקודמות מראות איך להחיל עיצוב, כמו Theme.AppCompat, סופק על ידי ספריית התמיכה של Android. עם זאת, בדרך כלל כדאי להתאים אישית את העיצוב כך שיתאים למותג של האפליקציה. הדרך הטובה ביותר לעשות זאת היא להרחיב את הסגנונות האלה מ-Support Library ולשנות את ערכי ברירת המחדל של חלק מהמאפיינים, כפי שמתואר בקטע הבא.

היררכיית סגנונות

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

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

  1. החלת סגנון ברמת התו או הפסקה באמצעות קטעי טקסט על כיתות שמבוססות על TextView.
  2. החלת מאפיינים באופן פרוגרמטי.
  3. החלת מאפיינים בודדים ישירות על תצוגה מפורטת.
  4. החלת סגנון על תצוגה מפורטת.
  5. עיצוב ברירת מחדל.
  6. החלת עיצוב על אוסף תצוגות, על פעילות או על האפליקציה כולה.
  7. החלת סגנון ספציפי לתצוגה מסוימת, למשל הגדרת 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 מרחיב את העיצוב מספריית התמיכה וכולל שינויים במאפייני הצבעים שנמצאים בשימוש לפי אלמנטים מרכזיים בממשק המשתמש, כמו סרגל האפליקציות לחצן פעולה צף, אם משתמשים בו. כך תוכלו להתאים אישית במהירות את עיצוב הצבעים של האפליקציה על ידי עדכון הצבעים שסופקו.

לדוגמה, קובץ 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" בטבלה שמציגה את ההפניות לכיתה. לדוגמה, כל התצוגות תומכות במאפייני 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>

אפשר גם להרחיב סגנונות של ווידג'טים, בדיוק כמו הרחבת סגנון אחר, ואז להחיל את סגנון הווידג'ט המותאם אישית בפריסה או בנושא.

מקורות מידע נוספים

למידע נוסף על עיצובים וסגנונות, אפשר לעיין במקורות המידע הבאים:

פוסטים בבלוגים