هندسة المعلومات

قدم Android 8.0 بنية معلومات جديدة لتطبيق الإعدادات لتبسيط طريقة تنظيم الإعدادات وتسهيل على المستخدمين العثور بسرعة على الإعدادات لتخصيص أجهزتهم التي تعمل بنظام 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
  • جزء لوحة المعلومات : 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

DashboardFragment هو مضيف لوحدات التحكم في تفضيلات نمط البرنامج المساعد. يرث الجزء من PreferenceFragment ويحتوي على خطافات لتوسيع وتحديث كل من قوائم التفضيلات الثابتة وقوائم التفضيلات الديناميكية.

التفضيلات الثابتة

يتم تعريف قائمة التفضيلات الثابتة في XML باستخدام علامة <Preference> . يستخدم تطبيق DashboardFragment طريقة getPreferenceScreenResId() لتحديد ملف XML الذي يحتوي على قائمة ثابتة من التفضيلات المراد عرضها.

التفضيلات الديناميكية

يمثل العنصر الديناميكي لوحة ذات نية تؤدي إلى نشاط خارجي أو داخلي. عادةً ما يؤدي القصد إلى صفحة إعداد مختلفة. على سبيل المثال، يعد عنصر الإعداد "Google" في الصفحة الرئيسية للإعدادات عنصرًا ديناميكيًا. يتم تعريف العناصر الديناميكية في AndroidManifest (تمت مناقشته أدناه) ويتم تحميلها من خلال FeatureProvider (المُعرف باسم DashboardFeatureProvider ).

تعتبر الإعدادات الديناميكية أكثر ثقلاً من الإعدادات التي تم تكوينها بشكل ثابت، لذلك يجب على المطورين عادةً تنفيذ الإعداد كإعداد ثابت. ومع ذلك، يمكن أن يكون الإعداد الديناميكي مفيدًا عندما ينطبق أي مما يلي:

  • لا يتم تنفيذ الإعداد مباشرة في تطبيق الإعدادات (مثل إدخال إعداد يتم تنفيذه بواسطة تطبيقات OEM/Carrier).
  • يجب أن يظهر الإعداد على الصفحة الرئيسية للإعدادات.
  • لديك بالفعل نشاط للإعداد ولا تريد تنفيذ التكوين الثابت الإضافي.

لتكوين نشاط كإعداد ديناميكي، قم بما يلي:

  • قم بتمييز النشاط كإعداد ديناميكي عن طريق إضافة عامل تصفية الغرض إلى النشاط.
  • أخبر تطبيق الإعدادات بالفئة التي ينتمي إليها. الفئة ثابتة، ويتم تعريفها في 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، كما هو موضح في هذا القسم.

PreferenceController في إصدار Android 9

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

يتم تعريف واجهة PreferenceController على أنها BasePreferenceController . على سبيل المثال، راجع التعليمات البرمجية في packages/apps/Settings/src/com/android/settings/core/ BasePreferenceController.java

هناك عدة فئات فرعية من BasePreferenceController ، يتم تعيين كل منها إلى نمط واجهة مستخدم محدد يدعمه تطبيق الإعدادات افتراضيًا. على سبيل المثال، يحتوي TogglePreferenceController على واجهة برمجة التطبيقات (API) التي تحدد مباشرة كيفية تفاعل المستخدم مع واجهة مستخدم التفضيلات المستندة إلى التبديل.

يحتوي 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 على واجهات برمجة التطبيقات (APIs) 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. قم بإضافة عنصر تفضيل جديد في XML. تأكد من أنه يحتوي على android:key فريد.
  3. حدد PreferenceController لهذا التفضيل في طريقة getPreferenceControllers() الخاصة بالصفحة.
    • في Android 8.x واختياريًا في Android 9، قم بإنشاء مثيل لـ 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 في الإعدادات. يجب أن تمر جميع الاختبارات الحالية والجديدة.
  • قم بإنشاء الإعدادات وتثبيتها، ثم افتح الصفحة التي يتم تعديلها يدويًا. يجب أن يتم تحديث الصفحة على الفور.