تنفيذ المظهر الداكن

تجربة طريقة "الكتابة"
‫Jetpack Compose هي مجموعة أدوات واجهة المستخدم التي يُنصح باستخدامها على Android. تعرَّف على كيفية استخدام السمات في Compose.

الشكل 1. المظهر الداكن

يتوفّر "المظهر الداكن" في الإصدار 10 من نظام التشغيل Android (المستوى 29 من واجهة برمجة التطبيقات) والإصدارات الأحدث. وتشمل المزايا ما يلي:

  • يقلّل من استهلاك الطاقة بشكل كبير، وذلك حسب تكنولوجيا شاشة الجهاز.
  • تحسين مستوى الرؤية للمستخدمين الذين يعانون من ضعف في النظر وللذين يتأثرون بالضوء الساطع
  • تسهّل استخدام الجهاز في بيئة الإضاءة المنخفضة.

ينطبق "المظهر الداكن" على واجهة مستخدم نظام Android والتطبيقات التي تعمل على الجهاز.

هناك ثلاث طرق لتفعيل المظهر الداكن في نظام التشغيل Android 10 والإصدارات الأحدث:

  • استخدِم إعدادات النظام من خلال الانتقال إلى الإعدادات > العرض > المظهر لتفعيل المظهر الداكن.
  • استخدِم مربّع "الإعدادات السريعة" للتبديل بين النُسق من لوحة الإشعارات عند تفعيل هذه الميزة.
  • على أجهزة Pixel، فعِّل وضع "توفير شحن البطارية" لتفعيل المظهر الداكن في الوقت نفسه. قد لا تدعم الأجهزة الأخرى هذا السلوك.

للحصول على تعليمات حول تطبيق مظهر داكن على المحتوى المستند إلى الويب باستخدام مكوّن WebView، يُرجى الاطّلاع على تعتيم محتوى الويب في WebView.

توفير المظهر الداكن في تطبيقك

لتفعيل المظهر الداكن، اضبط مظهر تطبيقك، الذي يمكن العثور عليه عادةً في res/values/styles.xml، على أن يكون مستمدًا من مظهر DayNight:

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

يمكنك أيضًا استخدام المظهر الداكن في Material Components:

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

يربط ذلك المظهر الرئيسي للتطبيق بعلامات الوضع الليلي التي يتحكّم فيها النظام، ويمنح التطبيق مظهرًا داكنًا تلقائيًا عند تفعيله.

المظاهر والأنماط

تجنَّب استخدام الألوان أو الرموز المضمّنة في الرمز البرمجي والمخصّصة للاستخدام في المظهر الفاتح. استخدِم سمات المظهر أو الموارد المؤهَّلة لوضع الليل بدلاً من ذلك.

تتسم سمتا المظهر بأهمية قصوى بالنسبة إلى المظهر الداكن، وهما:

  • ?android:attr/textColorPrimary: لون نص عام ويكون هذا اللون قريبًا من الأسود في المظهر الفاتح وقريبًا من الأبيض في المظهر الداكن. يحتوي على حالة غير مفعّلة.
  • ?attr/colorControlNormal: لون رمز عام يحتوي على حالة غير مفعّلة.

ننصح باستخدام مكوّنات Material Design، لأنّ نظام سمات الألوان، مثل سمات السمات ?attr/colorSurface و?attr/colorOnSurface، يوفّر إمكانية الوصول بسهولة إلى الألوان المناسبة. يمكنك تخصيص هذه السمات في المظهر.

تغيير المظاهر داخل التطبيق

يمكنك السماح للمستخدمين بتغيير مظهر التطبيق أثناء تشغيله. في ما يلي الخيارات المقترَحة:

  • فاتح
  • داكن
  • الإعداد التلقائي للنظام (الخيار التلقائي المقترَح)

تتطابق هذه الخيارات مباشرةً مع أوضاع AppCompat.DayNight:

لتبديل المظهر، اتّبِع الخطوات التالية:

  • في المستوى 31 لواجهة برمجة التطبيقات والإصدارات الأحدث، استخدِم UiModeManager#setApplicationNightMode لإعلام النظام بالمظهر الذي يعمل به تطبيقك. يتيح ذلك للنظام مطابقة المظهر أثناء عرض شاشة البداية.

  • في المستوى 30 لواجهة برمجة التطبيقات والإصدارات الأقدم، استخدِم AppCompatDelegate.setDefaultNightMode() للتبديل بين المظاهر.

Force Dark

يتضمّن نظام التشغيل Android 10 ميزة فرض المظهر الداكن التي تتيح للمطوّرين تطبيق مظهر داكن بسرعة بدون الحاجة إلى ضبط مظهر DayNight بشكل صريح.

تحلّل ميزة Force Dark كل عرض في تطبيقك ذي المظهر الفاتح وتطبّق مظهرًا داكنًا تلقائيًا قبل رسمه على الشاشة. يمكنك استخدام مزيج من ميزة "فرض الوضع الداكن" والتنفيذ الأصلي لتقليل الوقت اللازم لتنفيذ المظهر الداكن.

يجب أن توافق التطبيقات على استخدام ميزة "فرض المظهر الداكن" من خلال ضبط android:forceDarkAllowed="true" في مظهر النشاط. يتم ضبط هذه السمة على جميع المظاهر الفاتحة التي يوفّرها النظام وAndroidX، مثل Theme.Material.Light. عند استخدام ميزة Force Dark، اختبِر تطبيقك بدقة واستبعِد طرق العرض حسب الحاجة.

إذا كان تطبيقك يستخدم مظهرًا داكنًا، مثل Theme.Material، لن يتم تطبيق ميزة "فرض المظهر الداكن". وبالمثل، إذا كان مظهر تطبيقك مأخوذًا من مظهر DayNight، لن يتم تطبيق Force Dark بسبب التبديل التلقائي للمظهر.

إيقاف ميزة "فرض الوضع الداكن" في طريقة عرض

يمكن التحكّم في ميزة "فرض الوضع الداكن" في طرق عرض محدّدة باستخدام سمة التنسيق android:forceDarkAllowed أو باستخدام setForceDarkAllowed().

محتوى على الويب

للحصول على معلومات حول استخدام المظاهر الداكنة في المحتوى المستند إلى الويب، يمكنك الاطّلاع على تعتيم محتوى الويب في WebView. للاطّلاع على مثال على تطبيق المظهر الداكن على WebView، راجِع عرض WebView التوضيحي على GitHub.

أفضل الممارسات

تقدّم الأقسام التالية أفضل الممارسات لتنفيذ المظاهر الداكنة.

الإشعارات والأدوات

بالنسبة إلى مساحات عرض واجهة المستخدم التي تعرضها على الجهاز ولكن لا تتحكّم فيها مباشرةً، احرص على أن تعكس أي طرق عرض تستخدمها مظهر التطبيق المضيف. ومن الأمثلة على ذلك الإشعارات وwidgets مشغّل التطبيقات.

الإشعارات

استخدِم نماذج الإشعارات التي يوفّرها النظام، مثل MessagingStyle. وهذا يعني أنّ النظام مسؤول عن تطبيق نمط العرض الصحيح.

الأدوات وطرق عرض الإشعارات المخصّصة

بالنسبة إلى أدوات مشغّل التطبيقات أو إذا كان تطبيقك يستخدم طرق عرض مخصّصة لمحتوى الإشعارات، اختبِر المحتوى في كل من المظهرين الفاتح والداكن.

تشمل المشاكل الشائعة التي يجب الانتباه إليها ما يلي:

  • بافتراض أنّ لون الخلفية فاتح دائمًا
  • تضمين ألوان النص بشكل ثابت
  • ضبط لون خلفية مبرمَج أثناء استخدام لون النص التلقائي
  • استخدام رمز قابل للرسم بلون ثابت

في كل هذه الحالات، استخدِم سمات المظهر المناسبة بدلاً من الألوان المرمّزة.

شاشات التشغيل

إذا كان تطبيقك يتضمّن شاشة بدء مخصّصة، قد تحتاج إلى تعديلها لكي تتوافق مع المظهر المحدّد.

أزِل أي ألوان مبرمَجة، مثل ألوان الخلفية التي تم ضبطها برمجيًا على اللون الأبيض. استخدِم سمة ?android:attr/colorBackground بدلاً من ذلك.

التغييرات في الإعدادات

عندما يتغير مظهر التطبيق، سواء من خلال إعدادات النظام أو 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;
}