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
- 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
ใหม่ API ที่
มีการอธิบายข้อกำหนด PreferenceController
ในชื่อและ
เป็นเอกสารใน Javadoc
เราขอแนะนําอย่างยิ่งให้เพิ่มการทดสอบหน่วยสําหรับ PreferenceController
แต่ละรายการ
หากส่งการเปลี่ยนแปลงไปยัง AOSP คุณต้องทำการทดสอบ 1 หน่วย
หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับวิธีเขียนการทดสอบที่อิงตาม Robolectric โปรดดูที่
ไฟล์ Readme packages/apps/Settings/tests/robotests/README.md
สถาปัตยกรรมข้อมูลแบบปลั๊กอิน
ระบบจะใช้การตั้งค่าแต่ละรายการเป็นค่ากำหนด คุณย้ายค่ากำหนดจากหน้าหนึ่งไปยังอีกหน้าหนึ่งได้โดยง่าย
Android 8.0 ได้เปิดตัวเศษส่วนของโฮสต์สไตล์ปลั๊กอินที่มีรายการการตั้งค่าเพื่อให้ย้ายการตั้งค่าหลายรายการได้ง่ายขึ้น รายการการตั้งค่าคือ โมเดลดังกล่าวเป็นตัวควบคุมรูปแบบปลั๊กอิน ดังนั้น หน้าการตั้งค่าจึงสร้างขึ้นโดย ส่วนย่อยของโฮสต์เดียวและตัวควบคุมการตั้งค่าหลายรายการ
DashboardFragment
DashboardFragment
เป็นโฮสต์ของตัวควบคุมค่ากำหนดรูปแบบปลั๊กอิน
ข้อมูลโค้ดรับค่ามาจาก PreferenceFragment
และมีฮุกเพื่อขยายและอัปเดตทั้งรายการค่ากําหนดแบบคงที่และรายการค่ากําหนดแบบไดนามิก
ค่ากําหนดแบบคงที่
รายการค่ากำหนดแบบคงที่กำหนดไว้ใน XML โดยใช้แท็ก <Preference>
ต
การใช้งาน DashboardFragment
ใช้เมธอด
getPreferenceScreenResId()
เมธอดในการกำหนดว่าไฟล์ XML ใดมี
รายการค่ากำหนดแบบคงที่ที่จะแสดง
ค่ากำหนดแบบไดนามิก
รายการแบบไดนามิกแสดงการ์ดที่มี Intent ซึ่งนําไปสู่กิจกรรมภายนอกหรือภายใน โดยปกติแล้ว Intent จะนำไปยังหน้าการตั้งค่าอื่น ตัวอย่างเช่น
"Google" รายการการตั้งค่าในหน้าแรกของการตั้งค่าเป็นรายการแบบไดนามิก ระบบจะกําหนดรายการแบบไดนามิกใน AndroidManifest
(จะอธิบายด้านล่าง) และโหลดผ่าน FeatureProvider
(กําหนดเป็น
DashboardFeatureProvider
)
การตั้งค่าแบบไดนามิกนั้นใช้ภาระงานหนักกว่าการกำหนดค่าแบบคงที่ ดังนั้นตามปกติแล้วนักพัฒนาซอฟต์แวร์ควรใช้การตั้งค่าแบบคงที่ อย่างไรก็ตาม การตั้งค่าแบบไดนามิกอาจมีประโยชน์เมื่อเงื่อนไขใดๆ ต่อไปนี้เป็นจริง
- การตั้งค่านี้ไม่มีการใช้งานในแอปการตั้งค่าโดยตรง (เช่น การแทรกการตั้งค่าที่ใช้งานโดยแอป OEM/ผู้ให้บริการ)
- การตั้งค่านี้ควรปรากฏในหน้าแรกของการตั้งค่า
- คุณมีกิจกรรมสำหรับการตั้งค่านี้อยู่แล้ว และไม่ต้องการใช้ การกำหนดค่าแบบคงที่เพิ่มเติม
หากต้องการกําหนดค่ากิจกรรมเป็นการตั้งค่าแบบไดนามิก ให้ทําดังนี้
- ทำเครื่องหมายกิจกรรมเป็นการตั้งค่าแบบไดนามิกโดยเพิ่มตัวกรอง Intent ลงใน กิจกรรม
- บอกแอปการตั้งค่าว่าแอปนั้นอยู่ในหมวดหมู่ใด หมวดหมู่เป็นค่าคงที่
กำหนดไว้ใน
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
(กล่าวถึงด้านล่าง) แล้วก็คือ
แสดงใน UI เป็นรายการแบบผสม
PreferenceController
การติดตั้งใช้งาน PreferenceController
นั้นมีความแตกต่างกัน
ใน Android 9 และ Android 8.x ตามที่อธิบายไว้ใน
PreferenceController ใน Android 9 รุ่น
PreferenceController
มีตรรกะทั้งหมดในการโต้ตอบกับ
ค่ากำหนด ซึ่งรวมถึงการแสดง การอัปเดต การจัดทำดัชนีการค้นหา ฯลฯ
อินเทอร์เฟซของ PreferenceController
หมายถึง
BasePreferenceController
ตัวอย่างเช่น ดูโค้ดใน
packages/apps/Settings/src/com/android/settings/core/
BasePreferenceController.java
มีคลาสย่อยของ BasePreferenceController
อยู่หลายคลาส แต่ละคลาส
การแมปกับรูปแบบ UI ที่เฉพาะเจาะจงซึ่งแอปการตั้งค่ารองรับโดยค่าเริ่มต้น ตัวอย่างเช่น TogglePreferenceController
มี API ที่เชื่อมโยงโดยตรงกับวิธีที่ผู้ใช้ควรโต้ตอบกับ UI ค่ากําหนดแบบปุ่มเปิด/ปิด
BasePreferenceController
มี API เช่น
getAvailabilityStatus()
displayPreference()
handlePreferenceTreeClicked(),
ฯลฯ เอกสารโดยละเอียดสำหรับแต่ละ
API อยู่ในคลาสอินเทอร์เฟซ
ข้อจำกัดในการใช้ 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
มี API isAvailable()
,
displayPreference()
, handlePreferenceTreeClicked()
ฯลฯ ซึ่งสอดคล้องกับการโต้ตอบกับค่ากําหนด
ดูเอกสารประกอบโดยละเอียดเกี่ยวกับ API แต่ละรายการได้ในคลาสอินเทอร์เฟซ
ขณะติดตั้งค่ากำหนดลงในส่วนย่อย หน้าแดชบอร์ดมีวิธีในการ
แนบ PreferenceController
ก่อนเวลาแสดง ณ เวลาติดตั้ง
ตัวควบคุมต่อสายไฟเข้ากับส่วนย่อย ดังนั้นเหตุการณ์ที่เกี่ยวข้องในอนาคตทั้งหมดจึง
ที่ส่งไปยังตัวควบคุม
DashboardFragment
เก็บรายการ PreferenceControllers
ไว้ในหน้าจอ ที่ onCreate()
ของข้อมูลโค้ดแบบเป็นกลุ่ม ระบบจะเรียกใช้ตัวควบคุมทั้งหมดสําหรับเมธอด isAvailable()
และหากผลลัพธ์เป็น "จริง" ระบบจะเรียกใช้ displayPreference()
เพื่อประมวลผลตรรกะการแสดงผล
ใช้ DashboardFragment
ย้ายค่ากำหนดจากหน้า A ไป B
หากค่ากําหนดแสดงอยู่ในไฟล์ 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()
วิธี- ใน 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"/>
- ใน Android 8.x และ Android 9 (ไม่บังคับ) ให้สร้างอินสแตนซ์
สร้างค่ากำหนดแบบไดนามิก
- ดูว่าหน้าต้นทางและหน้าปลายทางอยู่ในหมวดหมู่ใด คุณดูข้อมูลนี้ได้ใน
DashboardFragmentRegistry
- สร้างกิจกรรมใหม่ใน
AndroidManifest
- เพิ่มข้อมูลเมตาที่จําเป็นลงในกิจกรรมใหม่เพื่อกําหนดการตั้งค่า ตั้งค่าค่าข้อมูลเมตาของ
com.android.settings.category
เป็นค่าเดียวกับที่กําหนดไว้ในขั้นตอนที่ 1
สร้างเพจใหม่
- สร้างส่วนย่อยใหม่โดยรับค่ามาจาก
DashboardFragment
- กำหนดหมวดหมู่ใน
DashboardFragmentRegistry
หมายเหตุ: ขั้นตอนนี้เป็นแบบไม่บังคับ หากไม่ต้องการค่ากําหนดแบบไดนามิกในหน้านี้ คุณก็ไม่จําเป็นต้องระบุคีย์หมวดหมู่
- ทําตามขั้นตอนเพื่อเพิ่มการตั้งค่าที่จําเป็นสําหรับหน้านี้ สำหรับข้อมูลเพิ่มเติม โปรดดูที่ส่วนการใช้งาน
การตรวจสอบความถูกต้อง
- ทำการทดสอบแบบ Robolectric ในการตั้งค่า การทดสอบที่มีอยู่และใหม่ทั้งหมดควรผ่าน
- บิลด์และติดตั้งการตั้งค่า จากนั้นเปิดหน้าเว็บที่จะแก้ไขด้วยตนเอง หน้าเว็บควรอัปเดตทันที