Android 8.0 đã ra mắt một cấu trúc thông tin mới cho ứng dụng Cài đặt để đơn giản hoá cách sắp xếp các chế độ cài đặt và giúp người dùng dễ dàng tìm thấy các chế độ cài đặt để tuỳ chỉnh thiết bị Android của họ. Android 9 đã giới thiệu một số điểm cải tiến để cung cấp thêm chức năng Cài đặt và triển khai dễ dàng hơn.
Ví dụ và nguồn
Hầu hết các trang trong phần Cài đặt hiện được triển khai bằng khung mới. Một ví dụ điển hình là DisplaySettings:
packages/apps/Settings/src/com/android/settings/DisplaySettings.java
Dưới đây là danh sách đường dẫn tệp cho các thành phần quan trọng:
- 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 (được giới thiệu trong Android 9):
packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java
Triển khai
Nhà sản xuất thiết bị nên điều chỉnh cấu trúc thông tin Cài đặt hiện có và chèn thêm các trang cài đặt bổ sung nếu cần cho phù hợp với các tính năng dành riêng cho đối tác. Việc di chuyển các tuỳ chọn ưu tiên từ trang cũ (triển khai dưới dạng SettingsPreferencePage
) sang trang mới (triển khai bằng DashboardFragment
) có thể phức tạp. Có thể bạn sẽ không triển khai lựa chọn ưu tiên trên
trang cũ bằng PreferenceController
.
Vì vậy, khi di chuyển một lựa chọn ưu tiên từ một trang cũ sang một trang mới, bạn cần tạo PreferenceController
và di chuyển mã vào trình điều khiển trước khi tạo thực thể cho mã đó trong DashboardFragment
mới. Các API mà PreferenceController
yêu cầu được mô tả trong tên và được ghi lại trong Javadoc.
Bạn nên thêm một bài kiểm thử đơn vị cho mỗi PreferenceController
.
Nếu thay đổi được gửi đến AOSP, thì bạn phải kiểm thử đơn vị.
Để biết thêm thông tin về cách viết chương trình kiểm thử dựa trên Robolectric, hãy xem tệp readme packages/apps/Settings/tests/robotests/README.md
.
Kiến trúc thông tin kiểu trình bổ trợ
Mỗi mục cài đặt được triển khai dưới dạng Lựa chọn ưu tiên. Bạn có thể dễ dàng di chuyển một Lựa chọn ưu tiên từ trang này sang trang khác.
Để dễ dàng di chuyển nhiều chế độ cài đặt, Android 8.0 đã ra mắt một mảnh máy chủ kiểu trình bổ trợ chứa các mục cài đặt. Các mục cài đặt được mô hình hoá dưới dạng trình điều khiển kiểu trình bổ trợ. Do đó, một trang cài đặt được tạo bằng một mảnh máy chủ và nhiều trình điều khiển cài đặt.
DashboardFragment
DashboardFragment
là máy chủ lưu trữ của các bộ điều khiển tuỳ chọn kiểu trình bổ trợ.
Mảnh này kế thừa từ PreferenceFragment
và có các trình nối để mở rộng và cập nhật cả danh sách lựa chọn ưu tiên tĩnh và danh sách lựa chọn ưu tiên động.
Lựa chọn ưu tiên tĩnh
Danh sách lựa chọn ưu tiên tĩnh được xác định trong XML bằng thẻ <Preference>
. Việc triển khai DashboardFragment
sử dụng phương thức getPreferenceScreenResId()
để xác định tệp XML chứa danh sách tĩnh các tuỳ chọn hiển thị.
Lựa chọn ưu tiên linh động
Một mục động đại diện cho một thẻ thông tin có ý định, dẫn đến một Hoạt động bên ngoài hoặc bên trong. Thông thường, ý định này sẽ dẫn đến một trang cài đặt khác. Ví dụ: mục cài đặt "Google" trong trang chủ Cài đặt là một mục động. Các mục động được xác định trong AndroidManifest
(sẽ thảo luận bên dưới) và được tải thông qua FeatureProvider
(được khai báo là
DashboardFeatureProvider
).
Chế độ cài đặt động có trọng số lớn hơn so với chế độ cài đặt được định cấu hình tĩnh. Vì vậy, thông thường, các nhà phát triển nên triển khai chế độ cài đặt này dưới dạng chế độ tĩnh. Tuy nhiên, chế độ cài đặt động có thể hữu ích khi đáp ứng một trong các điều kiện sau:
- Chế độ cài đặt này không được triển khai trực tiếp trong ứng dụng Cài đặt (chẳng hạn như chèn chế độ cài đặt do ứng dụng OEM/Nhà mạng triển khai).
- Cài đặt này sẽ xuất hiện trên trang chủ Cài đặt.
- Bạn đã có một Hoạt động cho chế độ cài đặt và không muốn triển khai thêm cấu hình tĩnh.
Để định cấu hình một Hoạt động dưới dạng chế độ cài đặt động, hãy làm như sau:
- Đánh dấu hoạt động là chế độ cài đặt động bằng cách thêm bộ lọc ý định vào hoạt động.
- Cho ứng dụng Cài đặt biết ứng dụng đó thuộc danh mục nào. Danh mục là một hằng số, được xác định trong
CategoryKey
. - Không bắt buộc: Thêm văn bản tóm tắt khi chế độ cài đặt này hiển thị.
Dưới đây là ví dụ lấy từ ứng dụng Cài đặt cho 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>
Tại thời điểm kết xuất, mảnh sẽ yêu cầu danh sách Lựa chọn ưu tiên từ cả XML tĩnh và chế độ cài đặt động được xác định trong AndroidManifest
. Cho dù PreferenceController
được xác định trong mã Java hay trong XML, DashboardFragment
đều quản lý logic xử lý của từng chế độ cài đặt thông qua PreferenceController
(xem phần thảo luận bên dưới). Sau đó, các sự kiện này sẽ hiển thị trong giao diện người dùng dưới dạng danh sách kết hợp.
PreferenceController
Có sự khác biệt giữa việc triển khai PreferenceController
trong Android 9 và Android 8.x, như mô tả trong phần này.
PreferenceController trong bản phát hành Android 9
PreferenceController
chứa mọi logic để tương tác với lựa chọn ưu tiên, bao gồm cả việc hiển thị, cập nhật, lập chỉ mục tìm kiếm, v.v.
Giao diện của PreferenceController
được xác định là BasePreferenceController
. Ví dụ: xem mã trong packages/apps/Settings/src/com/android/settings/core/
BasePreferenceController.java
Có một số lớp con của BasePreferenceController
, mỗi lớp con ánh xạ đến một kiểu giao diện người dùng cụ thể mà ứng dụng Cài đặt hỗ trợ theo mặc định. Ví dụ: TogglePreferenceController
có một API ánh xạ trực tiếp đến cách người dùng tương tác với giao diện người dùng ưu tiên dựa trên nút bật/tắt.
BasePreferenceController
có các API như getAvailabilityStatus()
, displayPreference()
, handlePreferenceTreeClicked(),
, v.v. Tài liệu chi tiết cho từng API nằm trong lớp giao diện.
Một hạn chế trong việc triển khai BasePreferenceController
(và các lớp con của nó như TogglePreferenceController
) là chữ ký của hàm khởi tạo phải khớp với một trong các giá trị sau:
public MyController(Context context, String key) {}
public MyController(Context context) {}
Trong khi cài đặt một tuỳ chọn ưu tiên cho mảnh, trang tổng quan cung cấp một phương thức để đính kèm PreferenceController
trước thời gian hiển thị. Tại thời điểm cài đặt, trình điều khiển được kết nối với mảnh để tất cả các sự kiện liên quan trong tương lai đều được gửi đến trình điều khiển.
DashboardFragment
lưu giữ danh sách PreferenceController
trên màn hình. Tại onCreate()
của mảnh, tất cả các bộ điều khiển được gọi cho phương thức getAvailabilityStatus()
và nếu phương thức này trả về true, thì displayPreference()
sẽ được gọi để xử lý logic hiển thị.
getAvailabilityStatus()
cũng quan trọng để cho khung Cài đặt biết những mục nào có sẵn trong quá trình tìm kiếm.
PreferenceController trong các bản phát hành Android 8.x
PreferenceController
chứa mọi logic để tương tác với lựa chọn ưu tiên, bao gồm cả việc hiển thị, cập nhật, lập chỉ mục tìm kiếm, v. v.
Tương ứng với các lượt tương tác ưu tiên, giao diện của
PreferenceController
có các API isAvailable()
,
displayPreference()
, handlePreferenceTreeClicked()
, v.v. Bạn có thể tìm thấy tài liệu chi tiết về từng API trong lớp giao diện.
Trong khi cài đặt một lựa chọn ưu tiên cho mảnh, trang tổng quan sẽ cung cấp một phương thức để đính kèm một PreferenceController
trước thời gian hiển thị. Tại thời điểm cài đặt, trình điều khiển được kết nối với mảnh để tất cả các sự kiện liên quan trong tương lai đều được gửi đến trình điều khiển.
DashboardFragment
lưu giữ danh sách PreferenceControllers
trên màn hình. Tại onCreate()
của mảnh, tất cả trình điều khiển sẽ được gọi cho phương thức isAvailable()
và nếu phương thức này trả về true, displayPreference()
sẽ được gọi để xử lý logic hiển thị.
Sử dụng DashboardFragment
Di chuyển lựa chọn ưu tiên từ trang A sang trang B
Nếu lựa chọn ưu tiên được liệt kê tĩnh trong tệp XML lựa chọn ưu tiên của trang gốc, hãy làm theo quy trình di chuyển Tĩnh cho bản phát hành Android ở bên dưới. Nếu không, hãy làm theo quy trình di chuyển Linh động cho bản phát hành Android.
Di chuyển tĩnh trong Android 9
- Tìm tệp XML ưu tiên cho trang gốc và trang đích. Bạn có thể tìm thấy thông tin này từ phương thức
getPreferenceScreenResId()
của trang. - Xoá tuỳ chọn này khỏi tệp XML của trang gốc.
- Thêm lựa chọn ưu tiên vào XML của trang đích.
- Xoá
PreferenceController
cho tuỳ chọn này khỏi quá trình triển khai Java của trang ban đầu. Thông thường, thư mục này nằm trongcreatePreferenceControllers()
. Bạn có thể khai báo trực tiếp bộ điều khiển ở định dạng XML.Lưu ý: Lựa chọn ưu tiên có thể không có
PreferenceController
. - Tạo bản sao
PreferenceController
trongcreatePreferenceControllers()
của trang đích. NếuPreferenceController
được xác định trong XML trong trang cũ, hãy xác địnhPreferenceController
trong XML cho trang mới.
Di chuyển động trong Android 9
- Tìm danh mục mà trang đích và trang gốc lưu trữ. Bạn có thể tìm thấy thông tin này trong
DashboardFragmentRegistry
. - Mở tệp
AndroidManifest.xml
chứa chế độ cài đặt bạn cần di chuyển và tìm mục Activity (Hoạt động) đại diện cho chế độ cài đặt này. - Đặt giá trị siêu dữ liệu của hoạt động cho
com.android.settings.category
thành khoá danh mục của trang mới.
Di chuyển tĩnh trong các bản phát hành Android 8.x
- Tìm tệp XML ưu tiên cho trang gốc và trang đích. Bạn có thể tìm thấy thông tin này trong phương thức
- Hãy xoá lựa chọn ưu tiên trong tệp XML của trang gốc.
- Thêm tuỳ chọn vào XML của trang đích.
- Xoá
PreferenceController
cho tuỳ chọn này trong quá trình triển khai Java của trang ban đầu. Thường thì tệp này nằm tronggetPreferenceControllers()
. - Tạo bản sao
PreferenceController
tronggetPreferenceControllers()
của trang đích.
getPreferenceScreenResId()
của trang.
Lưu ý: Lựa chọn ưu tiên có thể không có PreferenceController
.
Di chuyển động trong các bản phát hành Android 8.x
- Tìm danh mục lưu trữ trang gốc và trang đích. Bạn có thể tìm thấy thông tin này trong
DashboardFragmentRegistry
. - Mở tệp
AndroidManifest.xml
chứa chế độ cài đặt bạn cần di chuyển và tìm mục Activity (Hoạt động) đại diện cho chế độ cài đặt này. - Thay đổi giá trị siêu dữ liệu của hoạt động cho
com.android.settings.category
, đặt điểm giá trị thành khoá danh mục của trang mới.
Tạo lựa chọn ưu tiên mới trên một trang
Nếu tuỳ chọn ưu tiên được liệt kê tĩnh trong tệp XML ưu tiên của trang gốc, hãy làm theo quy trình tĩnh bên dưới. Nếu không, hãy làm theo quy trình động.
Tạo tuỳ chọn tĩnh
- Tìm các tệp XML ưu tiên cho trang. Bạn có thể tìm thấy thông tin này trong phương thức getPreferenceScreenResId() của trang.
- Thêm một mục Preference (Lựa chọn ưu tiên) mới trong tệp XML. Đảm bảo rằng lớp này có một
android:key
duy nhất. -
Hãy xác định
PreferenceController
cho lựa chọn ưu tiên này trong phương thứcgetPreferenceControllers()
của trang.- Trong Android 8.x và tuỳ ý trong Android 9, hãy tạo bản sao
PreferenceController
cho tuỳ chọn ưu tiên này trong phương thứccreatePreferenceControllers()
của trang.Nếu lựa chọn ưu tiên này đã tồn tại ở những nơi khác, thì có thể đã có
PreferenceController
cho lựa chọn đó. Bạn có thể sử dụng lạiPreferenceController
mà không cần tạo một mã mới. -
Kể từ Android 9, bạn có thể chọn khai báo
PreferenceController
trong XML bên cạnh tuỳ chọn. Ví dụ:<Preference android:key="reset_dashboard" android:title="@string/reset_dashboard_title" settings:controller="com.android.settings.system.ResetPreferenceController"/>
- Trong Android 8.x và tuỳ ý trong Android 9, hãy tạo bản sao
Tạo lựa chọn ưu tiên linh động
- Tìm danh mục mà trang đích và trang gốc lưu trữ. Bạn có thể tìm thấy
thông tin này trong
DashboardFragmentRegistry
. - Tạo một Hoạt động mới trong
AndroidManifest
- Thêm siêu dữ liệu cần thiết vào Hoạt động mới để xác định chế độ cài đặt. Đặt giá trị siêu dữ liệu cho
com.android.settings.category
thành cùng một giá trị được xác định ở bước 1.
Tạo một trang mới
- Tạo một mảnh mới, kế thừa từ
DashboardFragment
. - Xác định danh mục của nó trong
DashboardFragmentRegistry
.Lưu ý: Bước này là không bắt buộc. Nếu không cần bất kỳ lựa chọn ưu tiên động nào trong trang này, bạn không cần cung cấp khoá danh mục.
- Làm theo các bước để thêm các chế độ cài đặt cần thiết cho trang này. Để biết thêm thông tin, hãy xem phần Triển khai.
Xác nhận kết quả
- Chạy các kiểm thử robolectric trong phần Cài đặt. Tất cả các chương trình kiểm thử hiện có và mới đều phải vượt qua.
- Tạo và cài đặt phần Cài đặt, sau đó mở trang đang được sửa đổi theo cách thủ công. Trang sẽ cập nhật ngay lập tức.