資訊架構

Android 8.0 推出了全新的資訊架構,讓「設定」應用程式能 簡化設定的整理方式,並讓使用者 快速找出可自訂 Android 裝置的設定。 Android 9 推出了一些改善功能,可提供更多設定功能,並簡化實作程序。

範例和來源

「設定」中大部分的網頁目前都使用新架構來導入。不錯 例如 DisplaySettings: packages/apps/Settings/src/com/android/settings/DisplaySettings.java

重要元件的檔案路徑如下:

  • CategoryKeypackages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
  • DashboardFragmentRegistrypackages/apps/Settings/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
  • DashboardFragmentpackages/apps/Settings/src/com/android/settings/dashboard/DashboardFragment.java
  • AbstractPreferenceControllerframeworks/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 中執行個體化。Google Cloud 的 API PreferenceController要求提供姓名和 相關文件。

強烈建議您為每個 PreferenceController 新增單元測試。如果變更內容已提交至 Android 開放原始碼計畫,則必須進行單元測試。如要進一步瞭解如何編寫以 Robolectric 為基礎的測試,請參閱 readme 檔案 packages/apps/Settings/tests/robotests/README.md

外掛程式樣式資訊架構

每個設定項目都會做為偏好設定。建立偏好很容易 內容則從一個頁面移到另一個頁面

為方便您輕鬆移動多項設定,Android 8.0 推出了 包含設定項目的外掛程式樣式主機片段。設定項目為 模擬成外掛程式式控制器因此設定頁面是由 單一主機片段和多個設定控制器。

DashboardFragment

DashboardFragment 是外掛程式樣式偏好設定控制器的主機。片段繼承自 PreferenceFragment,且設有掛鉤 展開並更新靜態偏好設定清單和動態偏好設定清單。

靜態偏好設定

靜態偏好設定清單是在 XML 中使用 <Preference> 標記定義。A 罩杯 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>

在算繪期間,片段會要求 AndroidManifest 中定義的靜態 XML 和動態設定的偏好設定清單。無論 PreferenceController 是在 Java 程式碼或 XML 中定義,DashboardFragment 都會透過 PreferenceController 管理每個設定的處理邏輯 (詳見下文)。然後 而是以混合清單的形式顯示在 UI 中。

PreferenceController

導入 PreferenceController 有所差異 詳見本簡報 專區。

Android 9 中的 PreferenceController

PreferenceController 包含與偏好設定互動的所有邏輯,包括顯示、更新、搜尋索引等。

PreferenceController 的介面定義為 BasePreferenceController。例如,請參閱 packages/apps/Settings/src/com/android/settings/core/ BasePreferenceController.java 中的程式碼

BasePreferenceController 有幾個子類別,每個子類別都會對應至「設定」應用程式預設支援的特定 UI 樣式。適用對象 例如,TogglePreferenceController 的 API 可直接對應 如何與切換型偏好設定 UI 互動。

BasePreferenceController 包含 getAvailabilityStatus()displayPreference()handlePreferenceTreeClicked(), 等 API。每個 API 的詳細說明文件都在介面類別中。

實作 BasePreferenceController (以及 TogglePreferenceController 等子類別) 時,建構函式簽章必須符合下列任一條件:

  • public MyController(Context context, String key) {}
  • public MyController(Context context) {}

在片段中安裝偏好設定時,資訊主頁會提供一種方法,可在顯示時間前附加 PreferenceController。在安裝時 控制器會連接至片段,因此未來所有相關事件都會 就會傳送到控制器

DashboardFragment 會在畫面中保留 PreferenceController 清單。在片段的 onCreate(),系統會針對 getAvailabilityStatus() 方法,如果傳回 true, 叫用 displayPreference() 來處理顯示邏輯。 另外,「getAvailabilityStatus()」也相當重要。 比較哪些項目可在搜尋時派上用場

Android 8.x 版本中的 PreferenceController

PreferenceController 包含與偏好設定互動的所有邏輯,包括顯示、更新、搜尋索引等。

根據偏好設定互動, PreferenceController 的介面有 isAvailable() displayPreference()handlePreferenceTreeClicked() 等 API。您可以在介面類別中找到各個 API 的詳細說明文件。

在片段中安裝偏好設定時,資訊主頁會提供一種方法,可在顯示時間前附加 PreferenceController。在安裝時 控制器會連接至片段,因此未來所有相關事件都會 就會傳送到控制器

DashboardFragment 會在畫面中保留 PreferenceControllers 清單。在片段的 onCreate() 中,系統會為 isAvailable() 方法叫用所有控制器,如果該方法傳回 true,系統會叫用 displayPreference() 來處理顯示邏輯。

使用 DashboardFragment

將偏好設定從頁面 A 移至頁面 B

如果偏好設定是靜態列在原始網頁的偏好設定 XML 中 檔案,請按照 Android 靜態移動程序操作 。否則,請按照 Android 版本的動態移轉程序進行。

Android 9 中的靜態移動

  1. 找出原始頁面和目的地頁面的偏好設定 XML 檔案。您可以透過頁面的 getPreferenceScreenResId() 方法找到這項資訊。
  2. 移除原始網頁的 XML 偏好設定。
  3. 將偏好設定加入目的地網頁的 XML。
  4. 從原始頁面的 Java 實作中移除此偏好設定的 PreferenceController。這通常位於 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. 在原始頁面的 Java 實作中移除此偏好設定的 PreferenceController。通常主題為 getPreferenceControllers()
  6. 注意:偏好設定可能沒有 PreferenceController

  7. 在目的地網頁的 getPreferenceControllers() 中例項化 PreferenceController

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 中,請在頁面的 createPreferenceControllers() 方法中為此偏好設定例項化 PreferenceController

      如果這個偏好設定已存在於其他位置,則可能已為其建立 PreferenceController。您可以重複使用 PreferenceController,而無需建構新的 PreferenceController

    • 從 Android 9 開始,您可以選擇在偏好設定旁的 XML 中宣告 PreferenceController。例如:
      <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 測試。所有現有和新的測試都應該 略過
  • 建構並安裝設定,然後手動開啟要修改的頁面。網頁會立即更新。