بنية المعلومات

قدّم الإصدار 8.0 من نظام التشغيل Android بنية معلومات جديدة لتطبيق "الإعدادات" بهدف تبسيط طريقة تنظيم الإعدادات وتسهيل عثور المستخدمين على الإعدادات التي تتيح لهم تخصيص أجهزة 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، راجِع ملف 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() لإخبار إطار عمل &quot;الإعدادات&quot; بالعناصر المتاحة أثناء البحث.

‫PreferenceController في إصدارات Android 8.x

يحتوي PreferenceController على جميع العمليات المنطقية للتفاعل مع الإعداد المفضّل، بما في ذلك العرض والتعديل والفهرسة في البحث وما إلى ذلك.

بالنسبة إلى تفاعلات الإعدادات المفضّلة، تتضمّن واجهة PreferenceController واجهات برمجة تطبيقات isAvailable() و displayPreference() وhandlePreferenceTreeClicked() وما إلى ذلك. يمكن العثور على مستندات تفصيلية حول كل واجهة برمجة تطبيقات في فئة الواجهة.

أثناء تثبيت إعداد مفضّل في الجزء، توفّر لوحة البيانات طريقة لإرفاق PreferenceController قبل وقت العرض. عند التثبيت، يتم ربط وحدة التحكّم بالجزء، وبالتالي يتم إرسال جميع الأحداث المستقبلية ذات الصلة إلى وحدة التحكّم.

تحتفظ DashboardFragment بقائمة PreferenceControllers في الشاشة. في onCreate() الخاص بالجزء، يتم استدعاء جميع وحدات التحكّم من أجل الطريقة isAvailable()، وإذا كانت تعرض القيمة "صحيح"، يتم استدعاء displayPreference() لمعالجة منطق العرض.

استخدام DashboardFragment

نقل إعداد مفضّل من الصفحة (أ) إلى الصفحة (ب)

إذا كان الخيار مُدرجًا بشكل ثابت في ملف XML الخاص بخيارات الصفحة الأصلية، اتّبِع إجراء النقل الثابت لإصدار Android أدناه. بخلاف ذلك، اتّبِع إجراء النقل الديناميكي لإصدار Android.

عملية النقل الثابتة في Android 9

  1. ابحث عن ملفات XML الخاصة بالإعدادات المفضّلة لكل من الصفحة الأصلية وصفحة الوجهة. يمكنك العثور على هذه المعلومات من خلال طريقة getPreferenceScreenResId() للصفحة.
  2. أزِل الإعداد المفضّل من ملف XML الخاص بالصفحة الأصلية.
  3. أضِف الإعداد المفضّل إلى ملف XML الخاص بالصفحة المقصودة.
  4. أزِل PreferenceController لهذا الخيار من تنفيذ Java الخاص بالصفحة الأصلية. ويكون عادةً في createPreferenceControllers(). يمكن تعريف وحدة التحكّم مباشرةً في ملف XML.

    ملاحظة: قد لا يتضمّن الإعداد المفضّل PreferenceController.

  5. أنشئ مثيلاً من PreferenceController في createPreferenceControllers() بصفحة الوجهة. إذا تم تحديد PreferenceController في ملف XML الخاص بالصفحة القديمة، حدِّده في ملف XML الخاص بالصفحة الجديدة أيضًا.

التنقّل الديناميكي في Android 9

  1. ابحث عن الفئة التي تستضيفها الصفحة الأصلية والصفحة المقصودة. يمكنك الاطّلاع على هذه المعلومات في DashboardFragmentRegistry.
  2. افتح ملف AndroidManifest.xml الذي يتضمّن الإعداد الذي تريد نقله، وابحث عن إدخال النشاط الذي يمثّل هذا الإعداد.
  3. اضبط قيمة البيانات الوصفية للنشاط com.android.settings.category على مفتاح فئة الصفحة الجديدة.

النقل الثابت في إصدارات Android 8.x

  1. ابحث عن ملفات XML الخاصة بالإعدادات المفضّلة لكل من الصفحة الأصلية وصفحة الوجهة.
  2. يمكنك العثور على هذه المعلومات من خلال طريقة getPreferenceScreenResId() للصفحة.
  3. أزِل الإعداد المفضّل في ملف XML الخاص بالصفحة الأصلية.
  4. أضِف الإعداد المفضّل إلى ملف XML الخاص بالصفحة المقصودة.
  5. أزِل PreferenceController من هذا الخيار المفضّل في تطبيق Java الخاص بالصفحة الأصلية. ويكون عادةً في getPreferenceControllers().
  6. ملاحظة: من المحتمل ألا يتضمّن الإعداد المفضّل PreferenceController.

  7. أنشئ مثيلاً من PreferenceController في getPreferenceControllers() بصفحة الوجهة.

نقل البيانات بشكل ديناميكي في إصدارات Android 8.x

  1. ابحث عن الفئة التي تستضيفها الصفحة الأصلية والصفحة المقصودة. يمكنك العثور على هذه المعلومات في DashboardFragmentRegistry.
  2. افتح ملف AndroidManifest.xml الذي يتضمّن الإعداد الذي تريد نقله، وابحث عن إدخال النشاط الذي يمثّل هذا الإعداد.
  3. غيِّر قيمة البيانات الوصفية للنشاط com.android.settings.category، واضبط نقطة القيمة على مفتاح فئة الصفحة الجديدة.

إنشاء إعداد جديد مفضّل في صفحة

إذا كان الخيار مُدرجًا بشكل ثابت في ملف XML الخاص بخيارات الصفحة الأصلية، اتّبِع الإجراء الثابت أدناه. وإلا، اتّبِع الإجراءات الديناميكية.

إنشاء إعداد مفضّل ثابت

  1. ابحث عن ملفات XML الخاصة بالإعدادات المفضّلة للصفحة. يمكنك العثور على هذه المعلومات من خلال طريقة getPreferenceScreenResId() في الصفحة.
  2. أضِف عنصر Preference جديدًا في ملف XML. تأكَّد من أنّها تتضمّن android:key فريدًا.
  3. حدِّد PreferenceController لهذا الإعداد المفضّل في طريقة getPreferenceControllers() الخاصة بالصفحة.
    • في الإصدار 8.x من Android وفي الإصدار 9 من Android بشكل اختياري، أنشئ مثيلاً من PreferenceController لهذا الإعداد المفضّل في الطريقة createPreferenceControllers() للصفحة.

      إذا كان هذا الخيار متوفّرًا في أماكن أخرى، من المحتمل أن يكون هناك PreferenceController متاح له. يمكنك إعادة استخدام PreferenceController بدون إنشاء رمز جديد.

    • اعتبارًا من Android 9، يمكنك اختيار تعريف PreferenceController في XML بجانب الإعداد المفضّل. مثلاً:
      <Preference
              android:key="reset_dashboard"
              android:title="@string/reset_dashboard_title"
              settings:controller="com.android.settings.system.ResetPreferenceController"/>

إنشاء إعداد مفضّل ديناميكي

  1. ابحث عن الفئة التي تستضيفها الصفحة الأصلية والصفحة المقصودة. يمكنك العثور على هذه المعلومات في DashboardFragmentRegistry.
  2. إنشاء نشاط جديد في AndroidManifest
  3. أضِف البيانات الوصفية اللازمة إلى "النشاط" الجديد لتحديد الإعداد. اضبط قيمة البيانات الوصفية لـ com.android.settings.category على القيمة نفسها المحدّدة في الخطوة 1.

إنشاء صفحة جديدة

  1. أنشئ جزءًا جديدًا يرث من DashboardFragment.
  2. حدِّد فئته في DashboardFragmentRegistry.

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

  3. اتّبِع الخطوات لإضافة الإعدادات اللازمة لهذه الصفحة. لمزيد من المعلومات، يُرجى الاطّلاع على قسم التنفيذ.

التحقُّق

  • تشغيل اختبارات Robolectric في "الإعدادات" يجب أن تجتاز جميع الاختبارات الحالية والجديدة.
  • أنشئ تطبيق "الإعدادات" وثبِّته، ثم افتح يدويًا الصفحة التي يتم تعديلها. من المفترض أن يتم تعديل الصفحة على الفور.