طرَح 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، راجِع الملف التمهيدي packages/apps/Settings/tests/robotests/README.md
.
بنية المعلومات بنمط المكون الإضافي
يتم تنفيذ كل عنصر من عناصر الإعدادات باعتباره أحد عناصر الإعدادات المفضّلة. يمكن نقل التفضيلات بسهولة من صفحة إلى أخرى.
لتسهيل عملية نقل إعدادات متعددة، قدّم Android 8.0 جزء مضيف بنمط المكوّن الإضافي يحتوي على عناصر الإعدادات. يتم تصميم عناصر الإعدادات كوحدات تحكم بنمط المكونات الإضافية. وبالتالي، يتم إنشاء صفحة الإعدادات بواسطة جزء مضيف واحد ووحدات تحكُّم إعدادات متعددة.
قسم لوحة المعلومات
DashboardFragment
هو مضيف وحدات التحكّم في الإعدادات المفضّلة بنمط المكوّن الإضافي.
يتم اكتساب الجزء من PreferenceFragment
ويحتوي على عناصر الجذب لتوسيع وتعديل كل من قوائم الإعدادات المفضّلة الثابتة وقوائم الإعدادات المفضّلة الديناميكية.
الإعدادات المفضّلة الثابتة
يتم تحديد قائمة الإعدادات المفضّلة الثابتة في ملف XML باستخدام العلامة <Preference>
. يستخدم تنفيذ DashboardFragment
الطريقة getPreferenceScreenResId()
لتحديد ملف XML الذي يحتوي على قائمة ثابتة للإعدادات المفضّلة المطلوب عرضها.
الإعدادات المفضّلة الديناميكية
يمثّل العنصر الديناميكي مربّعًا غرضه أن يؤدّي إلى نشاط خارجي أو داخلي. وعادةً ما يؤدي الغرض إلى صفحة إعداد مختلفة. على سبيل المثال، يُعد عنصر الإعداد "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
في 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()
مهمًا أيضًا إعلام إطار عمل "الإعدادات" بالعناصر المتاحة أثناء البحث.
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()
الخاصة بالصفحة.
ملاحظة: من المحتمل ألا يحتوي التفضيل على
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
" - أضِف البيانات الوصفية اللازمة إلى النشاط الجديد لتحديد الإعداد. اضبط قيمة البيانات الوصفية للسمة
com.android.settings.category
على القيمة نفسها المحدّدة في الخطوة 1.
إنشاء صفحة جديدة
- إنشاء جزء جديد مكتسب من
DashboardFragment
- حدِّد فئته في
DashboardFragmentRegistry
.ملاحظة: هذه الخطوة اختيارية. إذا لم تكن بحاجة إلى أيّ إعدادات مفضّلة ديناميكية في هذه الصفحة، لن تحتاج إلى تقديم مفتاح فئة.
- اتّبِع الخطوات لإضافة الإعدادات المطلوبة لهذه الصفحة. لمزيد من المعلومات، يُرجى الاطّلاع على قسم التنفيذ.
التحقُّق
- يمكنك إجراء اختبارات الألعاب السلسة في "الإعدادات". يجب أن تنجح جميع الاختبارات الحالية والجديدة.
- أنشِئ الإعدادات وثبِّتها، ثم افتح الصفحة التي يتم تعديلها يدويًا. ومن المفترض أن يتم تعديل الصفحة على الفور.