طرَح Android 8.0 بنية معلومات جديدة لتطبيق "الإعدادات" لتبسيط طريقة تنظيم الإعدادات وتسهيل عثور المستخدمين على الإعدادات بسرعة لتخصيص أجهزة Android. قدّم الإصدار 9 من Android بعض التحسينات لتوفير المزيد من وظائف "الإعدادات" وتسهيل عملية التنفيذ.
الأمثلة والمصدر
يتم حاليًا تنفيذ معظم الصفحات في "الإعدادات" باستخدام إطار العمل الجديد. إليك مثال جيد:
DisplaySettings:
packages/apps/Settings/src/com/android/settings/DisplaySettings.java
في ما يلي مسارات الملفات للمكوّنات المهمة:
- CategoryKey:
packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
- DashboardFragmentRegistry:
packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
- DashboardFragment:
packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragment.java
- AbstractPreferenceController:
frameworks/base/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
- BasePreferenceController (تم طرحه في Android 9):
packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java
التنفيذ
ننصح الشركات المصنّعة للأجهزة بتكييف بنية معلومات الإعدادات الحالية وإدراج صفحات إعدادات إضافية حسب الحاجة لاستيعاب الميزات الخاصة بالمشرِك. يمكن أن يكون نقل الإعدادات المفضّلة من صفحة قديمة (تم تنفيذها باستخدام
SettingsPreferencePage
) إلى صفحة جديدة (تم تنفيذها باستخدام
DashboardFragment
) عملية معقّدة. من المحتمل أنّه لم يتم تنفيذ الإعدادات المفضّلة من الصفحة القديمة باستخدام PreferenceController
.
لذلك، عند نقل الإعدادات المفضّلة من صفحة قديمة إلى صفحة جديدة، عليك إنشاء ملف برمجي
PreferenceController
ونقل الرمز إلى وحدة التحكّم قبل
إنشاء مثيل له في DashboardFragment
الجديد. يتضمّن اسم واجهات برمجة التطبيقات
المطلوبة من قِبل "PreferenceController
"
ويتم توثيقها في Javadoc.
ننصحك بشدة بإضافة اختبار وحدة لكل PreferenceController
.
إذا تم إرسال التغيير إلى AOSP، يجب إجراء اختبار وحدات.
للحصول على مزيد من المعلومات حول كيفية كتابة الاختبارات المستندة إلى Robolectric، اطّلِع علىملف readmepackages/apps/Settings/tests/robotests/README.md
.
بنية المعلومات على غرار المكوّنات الإضافية
يتم تنفيذ كل عنصر من عناصر الإعدادات باعتباره أحد عناصر الإعدادات المفضّلة. يمكن نقل الإعدادات المفضّلة بسهولة من صفحة إلى أخرى.
لتسهيل نقل إعدادات متعددة، وفّر نظام التشغيل Android 8.0 شريحة مضيفة على غرار المكوّن الإضافي تحتوي على عناصر الإعدادات. يتم وضع عناصر الإعدادات على أنّها عناصر تحكّم على غرار المكوّنات الإضافية. وبالتالي، يتم إنشاء صفحة الإعدادات بواسطة جزء مضيف واحد ووحدات تحكُّم إعدادات متعددة.
قسم لوحة المعلومات
DashboardFragment
هو مضيف عناصر التحكّم في الإعدادات المفضّلة على غرار المكوّنات الإضافية.
يرث المقتطف PreferenceFragment
ويحتوي على عناصر ربط لتوسيع كلّ من قوائم الإعدادات المفضّلة الثابتة وقوائم الإعدادات المفضّلة الديناميكية وتعديلها.
الإعدادات المفضّلة الثابتة
يتم تحديد قائمة الإعدادات المفضّلة الثابتة في ملف XML باستخدام العلامة <Preference>
. يستخدم تنفيذ DashboardFragment
الطريقة getPreferenceScreenResId()
لتحديد ملف XML الذي يحتوي على قائمة ثابتة للإعدادات المفضّلة المطلوب عرضها.
الخيارات المفضّلة الديناميكية
يمثّل العنصر الديناميكي مربّع شاشة يتضمّن هدفًا يؤدي إلى activity خارجي أو داخلي. يؤدي الإجراء عادةً إلى صفحة إعدادات مختلفة. على سبيل المثال،
عنصر الإعداد "Google" في الصفحة الرئيسية لإعدادات Google هو عنصر ديناميكي. يتم تعريف العناصر
الديناميكية في AndroidManifest
(المُناقشة أدناه) ويتم تحميلها
من خلال FeatureProvider
(يُعرَّف على أنّه
DashboardFeatureProvider
).
تعتبر الإعدادات الديناميكية أكثر أهمية من الإعدادات التي تم ضبطها بشكل ثابت، لذا يجب على مطوّري البرامج عادةً تنفيذ الإعداد كإعدادات ثابتة. ومع ذلك، يمكن أن يكون الإعداد الديناميكي مفيدًا في الحالات التالية:
- لا يتم تنفيذ الإعداد مباشرةً في تطبيق "الإعدادات" (مثل إدخال إعداد ينفذه تطبيقات المصنّع الأصلي للجهاز أو مشغّل شبكة الجوّال).
- من المفترض أن يظهر الإعداد في الصفحة الرئيسية لإعدادات التطبيق.
- إذا كان لديك نشاط للإعداد ولا تريد تنفيذ الإعداد الثابت الإضافي
لضبط نشاط كإعداد ديناميكي، عليك إجراء ما يلي:
- ضَع علامة على النشاط كإعداد ديناميكي عن طريق إضافة فلتر أهداف إلى النشاط.
- أخبِر تطبيق "الإعدادات" بالفئة التي ينتمي إليها. الفئة هي ثابتة،
وتكون محدّدة في
CategoryKey
. - اختياري: أضِف نصًا موجزًا عند عرض الإعداد.
في ما يلي مثال مأخوذ من تطبيق "الإعدادات" على جهاز DisplaySettings
.
<activity android:name="Settings$DisplaySettingsActivity" android:label="@string/display_settings" android:icon="@drawable/ic_settings_display"> <!-- Mark the activity as a dynamic setting --> <intent-filter> <action android:name="com.android.settings.action.IA_SETTINGS" /> </intent-filter> <!-- Tell Settings app which category it belongs to --> <meta-data android:name="com.android.settings.category" android:value="com.android.settings.category.ia.homepage" /> <!-- Add a summary text when the setting is displayed --> <meta-data android:name="com.android.settings.summary" android:resource="@string/display_dashboard_summary"/> </activity>
في وقت العرض، سيطلب المقتطف قائمة بالإعدادات المفضّلة من كلّ من ملف XML الساكن
والإعدادات الديناميكية المحدّدة في AndroidManifest
. سواءً تم تعريف
PreferenceController
في رمز Java أو في XML، تدِير
DashboardFragment
منطق معالجة كلّ إعداد
من خلال PreferenceController
(الموضّح أدناه). ثم يتم عرضها في واجهة
المستخدم كقائمة مختلطة.
PreferenceController
هناك اختلافات بين تنفيذ PreferenceController
في Android 9 وAndroid 8.x، كما هو موضَّح في هذا القسم.
وحدة التحكّم المفضَّلة في إصدار Android 9
يحتوي PreferenceController
على كل المنطق للتفاعل مع الإعدادات المفضّلة، بما في ذلك العرض والتحديث والفهرسة في البحث وما إلى ذلك.
يتم تعريف واجهة PreferenceController
على النحو التالي:
BasePreferenceController
. على سبيل المثال، اطّلِع على الرمز في
packages/apps/Settings/src/com/android/settings/core/
BasePreferenceController.java
.
هناك عدة فئات فرعية من BasePreferenceController
، وكل منها مرتبط بأسلوب واجهة مستخدم معيّن يتيحه تطبيق "الإعدادات" تلقائيًا. على سبيل المثال، لدى TogglePreferenceController
واجهة برمجة تطبيقات ترتبط مباشرةً بكيفية تفاعل المستخدم مع واجهة مستخدم الإعدادات المفضّلة المستندة إلى زر الإيقاف/التفعيل.
تتضمّن BasePreferenceController
واجهات برمجة تطبيقات مثل
getAvailabilityStatus()
وdisplayPreference()
handlePreferenceTreeClicked(),
وما إلى ذلك. تتوفّر مستندات تفصيلية لكل واجهة برمجة تطبيقات في فئة الواجهة.
يتمثل أحد القيود المفروضة على تنفيذ BasePreferenceController
(وفئاته الفرعية مثل TogglePreferenceController
) في أنّ توقيع الدالة الإنشائية يجب أن يتطابق مع أي مما يلي:
public MyController(Context context, String key) {}
public MyController(Context context) {}
أثناء تثبيت إعداد مفضّل على المقتطف، توفّر لوحة البيانات طريقة ل
إرفاق PreferenceController
قبل وقت العرض. في وقت التثبيت، يتم ربط وحدة التحكّم بالجزء حتى يتم إرسال جميع الأحداث ذات الصلة في المستقبل إلى وحدة التحكّم.
DashboardFragment
" بقائمة تضم
"PreferenceController
" على الشاشة. في العنصر المجزّأ
onCreate()
، يتمّ استدعاء جميع وحدات التحكّم لطريقة
getAvailabilityStatus()
، وإذا كانت تعرض قيمة صحيحة، يتمّ استدعاء
displayPreference()
لمعالجة منطق العرض.
getAvailabilityStatus()
من المهم أيضًا إخبار إطار عمل "الإعدادات"getAvailabilityStatus()
بالعناصر المتوفّرة أثناء البحث.
PreferenceController في إصدارات Android 8.x
يحتوي PreferenceController
على كل المنطق للتفاعل مع الإعدادات المفضّلة، بما في ذلك العرض والتحديث والفهرسة في البحث وما إلى ذلك.
وفقًا للتفاعلات مع الإعدادات المفضّلة، تتضمّن واجهة
PreferenceController
واجهات برمجة التطبيقات isAvailable()
و
displayPreference()
وhandlePreferenceTreeClicked()
وما إلى ذلك.
يمكن العثور على مستندات تفصيلية حول كل واجهة برمجة تطبيقات في فئة الواجهة.
أثناء تثبيت تفضيل على الجزء، توفر لوحة البيانات طريقة
لإرفاق PreferenceController
قبل وقت العرض. في وقت التثبيت، يتم ربط وحدة التحكّم بالجزء حتى يتم إرسال جميع الأحداث ذات الصلة في المستقبل إلى وحدة التحكّم.
يحتفظ DashboardFragment
بقائمة PreferenceControllers
في الشاشة. في onCreate()
للّقطة، يتمّ استدعاء جميع
عناصر التحكّم لإجراء isAvailable()
، وإذا كانت
تُعرِض قيمة صحيحة، يتمّ استدعاء displayPreference()
لمعالجة منطق
العرض.
استخدام DashboardFragment
نقل تفضيل من الصفحة "أ" إلى "ب"
إذا كانت الإعدادات المفضّلة مُدرَجة بشكل ثابت في ملف XML الخاص بالإعدادات المفضّلة للصفحة الأصلية، اتّبِع إجراء النقل الثابت لإصدار Android المُستخدَم أدناه. بخلاف ذلك، اتّبِع إجراءات نقل البيانات الديناميكية لإصدار Android.
الحركة الثابتة في Android 9
- ابحث عن ملفات XML المفضّلة للصفحة الأصلية والوجهة
الصفحة. يمكنك العثور على هذه المعلومات من خلال طريقة
getPreferenceScreenResId()
للصفحة. - أزِل الإعدادات المفضّلة من ملف XML الخاص بالصفحة الأصلية.
- أضِف الإعداد المفضّل إلى ملف XML للصفحة المقصودة.
- أزِل الرمز
PreferenceController
لهذا الخيار المفضّل من تطبيق Java للصفحة الأصلية. ويكون عادةً بتنسيقcreatePreferenceControllers()
. قد يتم الإعلان عن وحدة التحكم في XML مباشرةً.ملاحظة: قد لا يتضمّن الخيار المفضّل رمز
PreferenceController
. - أنشئ مثيلًا للعنصر
PreferenceController
فيcreatePreferenceControllers()
للصفحة المقصودة. إذا تم تعريفPreferenceController
في ملف XML للصفحة القديمة، حدِّده في ملف XML للصفحة الجديدة أيضًا.
التنقّل الديناميكي في Android 9
- ابحث عن الفئة التي تستضيفها الصفحة الأصلية والصفحة المقصودة. يمكنك
الاطّلاع على هذه المعلومات في
DashboardFragmentRegistry
. - افتح ملف
AndroidManifest.xml
الذي يحتوي على الإعداد الذي تحتاج إلى نقله وابحث عن إدخال "النشاط" الذي يمثّل هذا الإعداد. - اضبط قيمة البيانات الوصفية للنشاط
com.android.settings.category
على مفتاح فئة الصفحة الجديدة.
حركة ثابتة في إصدارات Android 8.x
- ابحث عن ملفات XML للإعدادات المفضّلة للصفحة الأصلية والصفحة المقصودة. يمكنك العثور على هذه المعلومات من طريقة
- أزِل التفضيل من ملف XML الخاص بالصفحة الأصلية.
- أضِف الإعداد المفضّل إلى ملف XML للصفحة المقصودة.
- أزِل الرمز
PreferenceController
لهذا الخيار المفضّل في تطبيق Java للصفحة الأصلية. ويكون عادةً فيgetPreferenceControllers()
. - يمكنك إنشاء مثيل
PreferenceController
فيgetPreferenceControllers()
للصفحة المقصودة.
getPreferenceScreenResId()
الخاصة بالصفحة.
ملاحظة: من الممكن ألا يكون للإعداد المفضّل ملف شخصي على Google.PreferenceController
النقل الديناميكي في إصدارات Android 8.x
- ابحث عن الفئة التي تستضيف الصفحة الأصلية والصفحة المقصودة. يمكنك العثور على
هذه المعلومات في
DashboardFragmentRegistry
. - افتح ملف
AndroidManifest.xml
الذي يحتوي على الإعداد الذي تحتاج إلى نقله وابحث عن إدخال النشاط الذي يمثل هذا الإعداد. - غيِّر قيمة البيانات الوصفية للنشاط
com.android.settings.category
، وأضِف القيمة التي تشير إلى مفتاح فئة الصفحة الجديدة.
إنشاء إعداد مفضّل جديد في صفحة
إذا كانت الإعدادات المفضّلة مُدرَجة بشكل ثابت في ملف XML للإعدادات المفضّلة للصفحة الأصلية، اتّبِع الإجراء الثابت أدناه. في حال عدم توفّرها، يُرجى اتّباع الإجراء الديناميكي.
إنشاء إعداد مفضّل ثابت
- ابحث عن ملفات XML المفضّلة للصفحة. يمكنك العثور على هذه المعلومات من خلال الطريقة getPreferenceScreenResId() للصفحة.
- أضِف عنصر الإعدادات المفضّلة الجديد في ملف XML. تأكَّد من أنّه يحتوي على
android:key
فريد. -
حدِّد سمة
PreferenceController
لهذا الخيار المفضّل في طريقةgetPreferenceControllers()
للصفحة.- في الإصدار 8.x من Android والإصدار 9 من Android اختياريًا،
أنشئ مثيلًا لـ
PreferenceController
لهذا الخيار المفضّل فيcreatePreferenceControllers()
الصفحة.إذا كان هذا الخيار المفضّل متوفّرًا في مواضع أخرى، من المحتمل أن يكون هناك
PreferenceController
له. ويمكنك إعادة استخدام "PreferenceController
" بدون إنشاء أخرى جديدة. -
بدءًا من الإصدار 9 من نظام Android، يمكنك اختيار إعلان
PreferenceController
في XML بجانب الإعداد المفضّل. مثلاً:<Preference android:key="reset_dashboard" android:title="@string/reset_dashboard_title" settings:controller="com.android.settings.system.ResetPreferenceController"/>
- في الإصدار 8.x من Android والإصدار 9 من Android اختياريًا،
أنشئ مثيلًا لـ
إنشاء إعداد مفضّل ديناميكي
- ابحث عن الفئة التي تستضيفها الصفحة الأصلية والصفحة المقصودة. يمكنك العثور على
هذه المعلومات في
DashboardFragmentRegistry
. - إنشاء نشاط جديد في
AndroidManifest
- أضِف البيانات الوصفية اللازمة إلى النشاط الجديد لتحديد الإعداد. اضبط قيمة ال metadata لـ
com.android.settings.category
على القيمة نفسها التي تم تحديدها في الخطوة 1.
إنشاء صفحة جديدة
- إنشاء جزء جديد مكتسب من
DashboardFragment
- حدِّد فئتها في
DashboardFragmentRegistry
.ملاحظة: هذه الخطوة اختيارية. إذا لم تكن بحاجة إلى أيّ إعدادات مفضّلة ديناميكية في هذه الصفحة، ليس عليك تقديم مفتاح فئة.
- اتّبِع الخطوات لإضافة الإعدادات المطلوبة لهذه الصفحة. لمزيد من المعلومات، يُرجى الاطّلاع على قسم التنفيذ.
التحقُّق
- يمكنك إجراء اختبارات Robolectric في "الإعدادات". يجب اجتياز جميع الاختبارات الحالية والجديدة.
- أنشئ تطبيق "الإعدادات" وثبِّته، ثم افتح يدويًا الصفحة التي يتم تعديلها. من المفترض أن يتم تعديل الصفحة على الفور.