قدّم الإصدار 8.0 من نظام التشغيل Android بنية معلومات جديدة لتطبيق "الإعدادات" بهدف تبسيط طريقة تنظيم الإعدادات وتسهيل عثور المستخدمين على الإعدادات التي تتيح لهم تخصيص أجهزة Android بسرعة. قدّم نظام التشغيل Android 9 بعض التحسينات لتوفير المزيد من وظائف "الإعدادات" وتسهيل تنفيذها.
الأمثلة والمصدر
يتم حاليًا تنفيذ معظم الصفحات في "الإعدادات" باستخدام إطار العمل الجديد. من الأمثلة الجيدة على ذلك 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، راجِع ملف readme packages/apps/Settings/tests/robotests/README.md.
بنية المعلومات المستندة إلى الإضافات
يتم تنفيذ كل عنصر من عناصر الإعدادات كإعداد مفضّل. يمكن نقل أحد الإعدادات المفضّلة بسهولة من صفحة إلى أخرى.
لتسهيل نقل إعدادات متعدّدة، قدّمت الإصدار 8.0 من نظام التشغيل Android جزءًا مضيفًا على شكل مكوّن إضافي يحتوي على عناصر الإعدادات. يتم تصميم عناصر الإعدادات كوحدات تحكّم على شكل إضافات. وبالتالي، يتم إنشاء صفحة الإعدادات من خلال جزء مضيف واحد وعناصر تحكّم متعددة في الإعدادات.
DashboardFragment
DashboardFragment هو مضيف عناصر التحكّم في الإعدادات المفضّلة بنمط المكوّنات الإضافية.
يرث الجزء من PreferenceFragment ويتضمّن خطافات لتوسيع وتعديل كلّ من قوائم الإعدادات المفضّلة الثابتة وقوائم الإعدادات المفضّلة الديناميكية.
الإعدادات المفضّلة الثابتة
يتم تحديد قائمة الإعدادات المفضّلة الثابتة في XML باستخدام العلامة <Preference>. يستخدم تطبيق
DashboardFragment الطريقة
getPreferenceScreenResId() لتحديد ملف XML الذي يحتوي على
القائمة الثابتة للإعدادات المفضّلة التي سيتم عرضها.
الإعدادات المفضّلة الديناميكية
يمثّل العنصر الديناميكي مربّعًا يتضمّن هدفًا يؤدي إلى نشاط خارجي أو داخلي. يؤدي الغرض عادةً إلى صفحة إعدادات مختلفة. على سبيل المثال، عنصر الإعداد "Google" في الصفحة الرئيسية للإعدادات هو عنصر ديناميكي. يتم تحديد العناصر الديناميكية في AndroidManifest (الموضّحة أدناه) ويتم تحميلها من خلال FeatureProvider (المحدّدة على أنّها
DashboardFeatureProvider).
تكون الإعدادات الديناميكية أكثر تعقيدًا من الإعدادات التي يتم ضبطها بشكل ثابت، لذا على المطوّرين عادةً تنفيذ الإعدادات بشكل ثابت. ومع ذلك، يمكن أن يكون الإعداد الديناميكي مفيدًا في أيٍّ من الحالات التالية:
- لا يتم تنفيذ الإعداد مباشرةً في تطبيق "الإعدادات" (مثل إدخال إعداد تم تنفيذه بواسطة تطبيقات OEM/المشغّل).
- يجب أن يظهر الإعداد في الصفحة الرئيسية للإعدادات.
- لديك حاليًا نشاط للإعداد ولا تريد تنفيذ الإعدادات الثابتة الإضافية.
لضبط أحد الأنشطة كإعداد ديناميكي، اتّبِع الخطوات التالية:
- ضَع علامة على النشاط باعتباره إعدادًا ديناميكيًا من خلال إضافة فلتر أهداف إلى النشاط.
- أخبِر تطبيق "الإعدادات" بالفئة التي ينتمي إليها. الفئة هي قيمة ثابتة،
محدّدة في
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
في الإصدار 9 من نظام Android عن الإصدار 8.x، كما هو موضّح في هذا القسم.
PreferenceController في إصدار 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() لإخبار إطار عمل "الإعدادات" بالعناصر المتاحة أثناء البحث.
PreferenceController في إصدارات Android 8.x
يحتوي PreferenceController على جميع العمليات المنطقية للتفاعل مع الإعداد المفضّل، بما في ذلك العرض والتعديل والفهرسة في محرك البحث وما إلى ذلك.
بالنسبة إلى تفاعلات الإعدادات المفضّلة، تتضمّن واجهة
PreferenceController واجهات برمجة تطبيقات isAvailable() و
displayPreference() وhandlePreferenceTreeClicked() وما إلى ذلك.
يمكن العثور على مستندات مفصّلة حول كل واجهة برمجة تطبيقات في فئة الواجهة.
أثناء تثبيت إعداد مفضّل في الجزء، توفّر لوحة البيانات طريقة لإرفاق PreferenceController قبل وقت العرض. عند التثبيت، يتم ربط وحدة التحكّم بالجزء، وبالتالي يتم إرسال جميع الأحداث المستقبلية ذات الصلة إلى وحدة التحكّم.
تحتفظ DashboardFragment بقائمة PreferenceControllers
في الشاشة. في onCreate() للجزء، يتم استدعاء جميع وحدات التحكّم لتنفيذ الطريقة isAvailable()، وإذا عرضت القيمة "صحيح"، يتم استدعاء displayPreference() لمعالجة منطق العرض.
استخدام DashboardFragment
نقل إعداد مفضّل من الصفحة (أ) إلى الصفحة (ب)
إذا كان الخيار مُدرجًا بشكل ثابت في ملف XML الخاص بخيارات الصفحة الأصلية، اتّبِع إجراء النقل الثابت لإصدار Android أدناه. بخلاف ذلك، اتّبِع إجراء النقل الديناميكي لإصدار Android.
النقل الثابت في الإصدار 9 من نظام التشغيل Android
- ابحث عن ملفات 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()
للصفحة.
ملاحظة: من المحتمل ألا يتضمّن الإعداد المفضّل
PreferenceController.
نقل البيانات بشكل ديناميكي في إصدارات Android 8.x
- ابحث عن الفئة التي تستضيفها الصفحة الأصلية والصفحة المقصودة. يمكنك العثور على هذه المعلومات في
DashboardFragmentRegistry. - افتح ملف
AndroidManifest.xmlالذي يتضمّن الإعداد الذي تريد نقله، وابحث عن إدخال النشاط الذي يمثّل هذا الإعداد. - غيِّر قيمة البيانات الوصفية للنشاط
com.android.settings.category، واضبط نقطة القيمة على مفتاح فئة الصفحة الجديدة.
إنشاء إعدادات مفضّلة جديدة في صفحة
إذا كان الخيار مُدرجًا بشكل ثابت في ملف XML الخاص بخيارات الصفحة الأصلية، اتّبِع الإجراء الثابت أدناه. وإلا، اتّبِع الإجراءات الديناميكية.
إنشاء إعداد مفضّل ثابت
- ابحث عن ملفات XML الخاصة بالإعدادات المفضّلة للصفحة. يمكنك العثور على هذه المعلومات من خلال طريقة getPreferenceScreenResId() في الصفحة.
- أضِف عنصر Preference جديدًا في ملف 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 - أضِف البيانات الوصفية اللازمة إلى "النشاط" الجديد لتحديد الإعداد. اضبط قيمة البيانات الوصفية لـ
com.android.settings.categoryعلى القيمة نفسها المحدّدة في الخطوة 1.
إنشاء صفحة جديدة
- أنشئ جزءًا جديدًا يرث من
DashboardFragment. - حدِّد فئته في
DashboardFragmentRegistry.ملاحظة: هذه الخطوة اختيارية. إذا لم تكن بحاجة إلى أي إعدادات مفضّلة ديناميكية في هذه الصفحة، ليس عليك تقديم مفتاح فئة.
- اتّبِع الخطوات لإضافة الإعدادات اللازمة لهذه الصفحة. لمزيد من المعلومات، يُرجى الاطّلاع على قسم التنفيذ.
التحقُّق
- تشغيل اختبارات Robolectric في "الإعدادات" يجب أن تجتاز جميع الاختبارات الحالية والجديدة.
- أنشئ تطبيق "الإعدادات" وثبِّته، ثم افتح يدويًا الصفحة التي يتم تعديلها. من المفترض أن يتم تعديل الصفحة على الفور.