اندروید 8.0 معماری اطلاعات جدیدی را برای برنامه تنظیمات معرفی کرد تا نحوه سازماندهی تنظیمات را ساده کند و کاربران بتوانند به سرعت تنظیمات را برای سفارشی کردن دستگاه های اندرویدی خود پیدا کنند. اندروید 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 (معرفی شده در اندروید 9):
packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java
پیاده سازی
سازندگان دستگاه تشویق می شوند تا معماری اطلاعات تنظیمات موجود را تطبیق دهند و صفحات تنظیمات اضافی را در صورت نیاز برای تطبیق با ویژگی های خاص شریک درج کنند. انتقال تنظیمات برگزیده از صفحه قدیمی (که به عنوان SettingsPreferencePage
اجرا می شود) به یک صفحه جدید (اجرا شده با استفاده از DashboardFragment
) می تواند پیچیده باشد. ترجیحات صفحه قدیمی احتمالاً با PreferenceController
اجرا نمی شود.
بنابراین، هنگام انتقال تنظیمات ترجیحی از یک صفحه قدیمی به صفحه جدید، باید یک PreferenceController
ایجاد کنید و کد را قبل از نمونهسازی در DashboardFragment
جدید به کنترلر منتقل کنید. APIهایی که PreferenceController
نیاز دارد به نام آنها توضیح داده شده و در Javadoc مستند شده است.
به شدت توصیه می شود برای هر PreferenceController
یک تست واحد اضافه کنید. اگر تغییر به AOSP ارسال شود، آزمایش واحد مورد نیاز است. برای دریافت اطلاعات بیشتر در مورد نحوه نوشتن تستهای مبتنی بر Robolectric، به packages/apps/Settings/tests/robotests/README.md
مراجعه کنید.
معماری اطلاعات به سبک پلاگین
هر مورد تنظیمات به عنوان یک اولویت اجرا می شود. یک Preference را می توان به راحتی از یک صفحه به صفحه دیگر منتقل کرد.
برای سهولت در جابجایی چندین تنظیمات، اندروید 8.0 یک قطعه میزبان به سبک پلاگین را معرفی کرد که حاوی موارد تنظیمات است. موارد تنظیمات بهعنوان کنترلکنندههای سبک پلاگین مدلسازی میشوند. از این رو، یک صفحه تنظیمات توسط یک قطعه میزبان و چندین کنترل کننده تنظیم ساخته می شود.
DashboardFragment
DashboardFragment
میزبان کنترلرهای ترجیحی به سبک پلاگین است. قطعه از PreferenceFragment
به ارث می رسد و دارای قلاب هایی برای گسترش و به روز رسانی لیست های ترجیحی ثابت و لیست های اولویت پویا است.
ترجیحات استاتیک
یک لیست ترجیحی ثابت در XML با استفاده از تگ <Preference>
تعریف می شود. یک پیاده سازی DashboardFragment
از متد getPreferenceScreenResId()
استفاده می کند تا مشخص کند کدام فایل XML حاوی لیست ایستا ترجیحات برای نمایش است.
ترجیحات پویا
یک آیتم پویا نشان دهنده یک کاشی با قصد است که منجر به یک فعالیت خارجی یا داخلی می شود. معمولاً هدف به صفحه تنظیمات متفاوتی منتهی می شود. به عنوان مثال، آیتم تنظیم "Google" در صفحه اصلی تنظیمات یک مورد پویا است. موارد پویا در AndroidManifest
تعریف میشوند (در زیر بحث میشود) و از طریق FeatureProvider
(تعریف شده به عنوان DashboardFeatureProvider
) بارگیری میشوند.
تنظیمات پویا سنگینتر از تنظیمات پیکربندی استاتیک هستند، بنابراین معمولاً توسعهدهندگان باید تنظیمات را بهعنوان یک تنظیمات ثابت پیادهسازی کنند. با این حال، تنظیم پویا زمانی می تواند مفید باشد که یکی از موارد زیر درست باشد:
- این تنظیم مستقیماً در برنامه تنظیمات (مانند تزریق تنظیماتی که توسط برنامههای OEM/Carrier اجرا شده است) اجرا نمیشود.
- این تنظیم باید در صفحه اصلی تنظیمات ظاهر شود.
- شما قبلاً یک Activity برای تنظیم دارید و نمی خواهید پیکربندی استاتیک اضافی را پیاده سازی کنید.
برای پیکربندی یک Activity به عنوان یک تنظیم پویا، موارد زیر را انجام دهید:
- با افزودن یک فیلتر قصد به فعالیت، فعالیت را به عنوان یک تنظیم پویا علامت گذاری کنید.
- به برنامه تنظیمات بگویید به کدام دسته تعلق دارد. دسته یک ثابت است که در
CategoryKey
تعریف شده است. - اختیاری: هنگامی که تنظیمات نمایش داده می شود، متن خلاصه را اضافه کنید.
در اینجا یک مثال از برنامه Settings برای 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
ها در کد جاوا تعریف شده باشند یا در XML، DashboardFragment
منطق مدیریت هر تنظیمات را از طریق PreferenceController
مدیریت می کند (در زیر بحث شده است). سپس آنها در UI به عنوان یک لیست ترکیبی نمایش داده می شوند.
PreferenceController
تفاوت هایی بین اجرای PreferenceController
در اندروید 9 و اندروید 8.x وجود دارد، همانطور که در این بخش توضیح داده شد.
PreferenceController در نسخه اندروید 9
یک PreferenceController
شامل تمام منطق برای تعامل با اولویت است، از جمله نمایش، به روز رسانی، فهرست بندی جستجو و غیره.
رابط PreferenceController
به عنوان BasePreferenceController
تعریف می شود. برای مثال، کد را در packages/apps/Settings/src/com/android/settings/core/ BasePreferenceController.java
ببینید.
چندین زیر کلاس از BasePreferenceController
وجود دارد که هر کدام به یک سبک UI خاص که برنامه تنظیمات به طور پیش فرض از آن پشتیبانی می کند، نگاشت می شود. به عنوان مثال، TogglePreferenceController
یک API دارد که مستقیماً نحوه تعامل کاربر با یک رابط کاربری ترجیحی مبتنی بر جابجایی را ترسیم می کند.
BasePreferenceController
دارای APIهایی مانند getAvailabilityStatus()
، displayPreference()
، handlePreferenceTreeClicked(),
مستندات دقیق برای هر API در کلاس رابط موجود است.
یک محدودیت در پیاده سازی BasePreferenceController
(و زیر کلاس های آن مانند TogglePreferenceController
) این است که امضای سازنده باید با یکی از موارد زیر مطابقت داشته باشد:
-
public MyController(Context context, String key) {}
-
public MyController(Context context) {}
در حین نصب اولویت برای قطعه، داشبورد روشی را برای اتصال PreferenceController
قبل از زمان نمایش ارائه می دهد. در زمان نصب، کنترلکننده به قطعه سیمکشی میشود، بنابراین تمام رویدادهای مرتبط آینده به کنترلکننده ارسال میشوند.
DashboardFragment
لیستی از PreferenceController
ها را در صفحه نگه می دارد. در onCreate()
فرگمنت، همه کنترلرها برای متد getAvailabilityStatus()
فراخوانی می شوند و اگر مقدار true را برگرداند، displayPreference()
برای پردازش منطق نمایش فراخوانی می شود. getAvailabilityStatus()
همچنین برای اطلاع دادن به چارچوب تنظیمات مهم است که چه مواردی در طول جستجو در دسترس هستند. PreferenceController در نسخه های اندروید 8.x منتشر شده است
یک PreferenceController
شامل تمام منطق برای تعامل با اولویت است، از جمله نمایش، به روز رسانی، فهرست بندی جستجو. و غیره
مطابق با تعاملات ترجیحی، رابط PreferenceController
دارای APIهای isAvailable()
، displayPreference()
، handlePreferenceTreeClicked()
و غیره است. مستندات دقیق در مورد هر API را می توان در کلاس رابط یافت.
در حین نصب اولویت برای قطعه، داشبورد روشی را برای اتصال PreferenceController
قبل از زمان نمایش ارائه می دهد. در زمان نصب، کنترلکننده به قطعه سیمکشی میشود، بنابراین تمام رویدادهای مرتبط آینده به کنترلکننده ارسال میشوند.
DashboardFragment
لیستی از PreferenceControllers
را در صفحه نگه می دارد. در onCreate()
فرگمنت، تمام کنترلرها برای متد isAvailable()
فراخوانی می شوند و اگر مقدار true را برگرداند، displayPreference()
برای پردازش منطق نمایش فراخوانی می شود.
از DashboardFragment استفاده کنید
یک اولویت را از صفحه A به B منتقل کنید
اگر اولویت به صورت ایستا در فایل XML ترجیحی صفحه اصلی فهرست شده است، رویه حرکت Static را برای نسخه اندروید خود در زیر دنبال کنید. در غیر این صورت، رویه حرکت پویا را برای نسخه اندروید خود دنبال کنید.
حرکت استاتیک در اندروید 9
- فایل های XML ترجیحی را برای صفحه اصلی و صفحه مقصد پیدا کنید. می توانید این اطلاعات را از متد
getPreferenceScreenResId()
صفحه پیدا کنید. - اولویت را از XML صفحه اصلی حذف کنید.
- اولویت را به XML صفحه مقصد اضافه کنید.
-
PreferenceController
را برای این اولویت از پیاده سازی جاوا صفحه اصلی حذف کنید. معمولاً درcreatePreferenceControllers()
است. کنترلر ممکن است مستقیماً در XML اعلام شود.توجه : ترجیح ممکن است
PreferenceController
نداشته باشد. -
PreferenceController
را درcreatePreferenceControllers()
صفحه مقصد نمونه سازی کنید. اگرPreferenceController
در صفحه قدیمی در XML تعریف شده است، آن را برای صفحه جدید نیز در XML تعریف کنید.
حرکت پویا در اندروید 9
- پیدا کنید کدام دسته میزبان صفحه اصلی و مقصد است. می توانید این اطلاعات را در
DashboardFragmentRegistry
بیابید. - فایل
AndroidManifest.xml
را که حاوی تنظیماتی است که باید جابجا کنید باز کنید و ورودی Activity را که این تنظیم را نشان می دهد پیدا کنید. - مقدار فراداده فعالیت را برای
com.android.settings.category
روی کلید دسته بندی صفحه جدید تنظیم کنید.
حرکت ایستا در نسخه های اندروید 8.x
- فایل های XML ترجیحی را برای صفحه اصلی و صفحه مقصد پیدا کنید. می توانید این اطلاعات را از متد
- اولویت را در XML صفحه اصلی حذف کنید.
- اولویت را به XML صفحه مقصد اضافه کنید.
-
PreferenceController
را برای این اولویت در پیاده سازی جاوا صفحه اصلی حذف کنید. معمولاً درgetPreferenceControllers()
است. -
PreferenceController
را درgetPreferenceControllers()
صفحه مقصد نمونه سازی کنید.
getPreferenceScreenResId()
صفحه پیدا کنید. توجه: ممکن است اولویت دارای PreferenceController
نباشد.
حرکت پویا در نسخه های اندروید 8.x
- پیدا کنید کدام دسته میزبان صفحه اصلی و مقصد است. می توانید این اطلاعات را در
DashboardFragmentRegistry
بیابید. - فایل
AndroidManifest.xml
را که حاوی تنظیماتی است که باید جابجا کنید باز کنید و ورودی Activity که این تنظیم را نشان می دهد را پیدا کنید. - مقدار فراداده فعالیت را برای
com.android.settings.category
تغییر دهید، نقطه مقدار را روی کلید دسته بندی صفحه جدید تنظیم کنید.
یک اولویت جدید در یک صفحه ایجاد کنید
اگر اولویت به صورت ایستا در فایل XML ترجیحی صفحه اصلی فهرست شده است، روش ثابت زیر را دنبال کنید. در غیر این صورت رویه پویا را دنبال کنید.
یک اولویت ثابت ایجاد کنید
- فایل های XML ترجیحی را برای صفحه پیدا کنید. می توانید این اطلاعات را از متد ()getPreferenceScreenResId صفحه پیدا کنید.
- یک آیتم Preference جدید در XML اضافه کنید. مطمئن شوید که یک
android:key
منحصر به فرد دارد. - در متد
getPreferenceControllers()
صفحه یکPreferenceController
برای این اولویت تعریف کنید.- در Android 8.x و به صورت اختیاری در Android 9، یک
PreferenceController
را برای این اولویت در متدcreatePreferenceControllers()
صفحه نمونه سازی کنید.اگر این اولویت قبلاً در جاهای دیگر وجود داشته است، ممکن است قبلاً یک
PreferenceController
برای آن وجود داشته باشد. میتوانید بدون ساختن یک کنترلر جدید، دوباره ازPreferenceController
استفاده کنید. - با شروع اندروید 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
ایجاد کنید - برای تعریف تنظیمات، متادیتای لازم را به Activity جدید اضافه کنید. مقدار فراداده را برای
com.android.settings.category
روی همان مقدار تعریف شده در مرحله 1 تنظیم کنید.
یک صفحه جدید ایجاد کنید
- یک قطعه جدید ایجاد کنید که از
DashboardFragment
به ارث می رسد. - دسته بندی آن را در
DashboardFragmentRegistry
تعریف کنید.توجه: این مرحله اختیاری است. اگر در این صفحه نیازی به تنظیمات پویا ندارید، نیازی به ارائه کلید دسته ندارید.
- مراحل اضافه کردن تنظیمات مورد نیاز برای این صفحه را دنبال کنید. برای اطلاعات بیشتر به بخش پیاده سازی مراجعه کنید.
اعتبار سنجی
- تست های روبولکتریک را در تنظیمات اجرا کنید. تمام آزمون های موجود و جدید باید قبول شوند.
- تنظیمات را بسازید و نصب کنید، سپس به صورت دستی صفحه در حال تغییر را باز کنید. صفحه باید فورا به روز شود.