הטמעת עיצוב כהה

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

איור 1. עיצוב כהה.

העיצוב הכהה זמין ב-Android 10 (רמת API‏ 29) ואילך. היתרונות של התכונה:

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

העיצוב הכהה חל על ממשק המשתמש של מערכת Android ועל אפליקציות שפועלות במכשיר.

יש שלוש דרכים להפעיל את העיצוב הכהה ב-Android מגרסה 10 ואילך:

  • כדי להפעיל את העיצוב הכהה, עוברים אל הגדרות > תצוגה > עיצוב.
  • אם מפעילים את האפשרות, אפשר להשתמש בכפתור ב'הגדרות מהירות' כדי להחליף בין ערכות נושא ממגש ההתראות.
  • במכשירי Pixel, מפעילים את מצב החיסכון בסוללה כדי להפעיל את העיצוב הכהה בו-זמנית. במכשירים אחרים יכול להיות שאי אפשר יהיה לבצע את הפעולה הזו.

הוראות להחלת עיצוב כהה על תוכן מבוסס-אינטרנט באמצעות רכיב WebView זמינות במאמר הכהיית תוכן אינטרנט ב-WebView.

תמיכה בעיצוב כהה באפליקציה

כדי לתמוך בעיצוב כהה, צריך להגדיר את העיצוב של האפליקציה – בדרך כלל הוא נמצא ב-res/values/styles.xml – כך שיירש מ-DayNight:

<style name="AppTheme" parent="Theme.AppCompat.DayNight">

אפשר גם להשתמש בעיצוב כהה של רכיבי Material:

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">

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

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

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

שני מאפייני עיצוב חשובים במיוחד לעיצוב כהה:

  • ?android:attr/textColorPrimary: צבע טקסט לשימוש כללי. הוא כמעט שחור בעיצוב בהיר וכמעט לבן בעיצוב כהה. הוא מכיל מצב מושבת.
  • ?attr/colorControlNormal: צבע הסמל לשימוש כללי. הוא מכיל מצב מושבת.

מומלץ להשתמש ברכיבים של Material Design, כי מערכת הצבעים שלה, כמו מאפייני הנושא ?attr/colorSurface ו-?attr/colorOnSurface, מספקת גישה נוחה לצבעים מתאימים. אפשר להתאים אישית את המאפיינים האלה בעיצוב.

שינוי העיצוב באפליקציה

אתם יכולים לאפשר למשתמשים לשנות את העיצוב של האפליקציה בזמן שהיא פועלת. אלה האפשרויות המומלצות:

  • בהיר
  • כהה
  • ברירת המחדל של המערכת (אפשרות ברירת המחדל המומלצת)

האפשרויות האלה ממופות ישירות למצבי AppCompat.DayNight:

כדי לשנות את העיצוב:

  • ברמת API ‏31 ומעלה, משתמשים ב-UiModeManager#setApplicationNightMode כדי להודיע למערכת באיזה עיצוב האפליקציה פועלת. כך המערכת יכולה להתאים את העיצוב במהלך מסך הפתיחה.

  • ברמת API 30 ומטה, משתמשים ב-AppCompatDelegate.setDefaultNightMode() כדי להחליף את העיצוב.

הפעלה ידנית של מצב כהה

‫Android 10 כולל את התכונה הפעלה ידנית של מצב כהה, שמאפשרת למפתחים להטמיע במהירות עיצוב כהה בלי להגדיר במפורש עיצוב DayNight.

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

כדי להשתמש באפשרות 'הפעלה ידנית של מצב כהה' באפליקציות, צריך להגדיר את android:forceDarkAllowed="true" בעיצוב של הפעילות. המאפיין הזה מוגדר בכל ערכות העיצוב הבהירות שסופקו על ידי המערכת ו-AndroidX, כמו Theme.Material.Light. כשמשתמשים ב'הפעלה ידנית של מצב כהה', חשוב לבדוק את האפליקציה באופן יסודי ולהחריג תצוגות לפי הצורך.

אם האפליקציה משתמשת בעיצוב כהה, כמו Theme.Material), לא מוחלת עליה 'הפעלה ידנית של מצב כהה'. באופן דומה, אם העיצוב של האפליקציה שלכם עובר בירושה מעיצוב DayNight, העיצוב הכהה לא מופעל בגלל המעבר האוטומטי בין העיצובים.

השבתת הפעלה ידנית של מצב כהה בתצוגה מפורטת

אפשר לשלוט בהפעלה ידנית של מצב כהה בתצוגות ספציפיות באמצעות מאפיין הפריסה android:forceDarkAllowed או באמצעות setForceDarkAllowed().

תוכן מהאינטרנט

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

שיטות מומלצות

בקטעים הבאים מפורטות שיטות מומלצות להטמעת ערכות נושא כהות.

התראות ווידג'טים

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

התראות

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

ווידג'טים ותצוגות של התראות בהתאמה אישית

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

בעיות נפוצות שכדאי להיזהר מהן:

  • בהנחה שצבע הרקע תמיד בהיר.
  • קידוד קשיח של צבעי טקסט.
  • הגדרת צבע רקע שמוגדר מראש בזמן השימוש בצבע הטקסט שמוגדר כברירת מחדל.
  • שימוש בסמל drawable שהוא צבע סטטי.

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

מסכי הפעלה

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

הסרת צבעים שמוגדרים בהארדקוד, כמו צבעי רקע שמוגדרים באופן פרוגרמטי ללבן. במקום זאת, צריך להשתמש במאפיין ?android:attr/colorBackground theme [נושא].

שינויים בהגדרות

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

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

אפליקציה יכולה לטפל בהטמעה של העיצוב הכהה על ידי הצהרה שכל Activity יכול לטפל בשינוי ההגדרה uiMode:

<activity
    android:name=".MyActivity"
    android:configChanges="uiMode" />

כש-Activity מצהיר שהוא מטפל בשינויים בהגדרות, השיטה onConfigurationChanged() שלו מופעלת כשמתבצע שינוי בעיצוב.

כדי לבדוק מהו העיצוב הנוכחי, אפליקציות יכולות להריץ קוד כמו זה:

Kotlin

val currentNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
when (currentNightMode) {
    Configuration.UI_MODE_NIGHT_NO -> {} // Night mode is not active, we're using the light theme.
    Configuration.UI_MODE_NIGHT_YES -> {} // Night mode is active, we're using dark theme.
}

Java

int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
    case Configuration.UI_MODE_NIGHT_NO:
        // Night mode is not active, we're using the light theme
        break;
    case Configuration.UI_MODE_NIGHT_YES:
        // Night mode is active, we're using dark theme
        break;
}