整理设置 Android Jetpack 的一部分。
如果设置屏幕庞大繁杂,用户将难以找到想要更改的具体设置。Preference 库可以通过以下几种方式更好地整理设置屏幕。
偏好设置类别
如果一个屏幕上有多个相关的 Preference
对象,您可以使用 PreferenceCategory
将它们分组。PreferenceCategory
显示类别标题,并在视觉上划分类别。
如需在 XML 中定义 PreferenceCategory
,请使用 PreferenceCategory
封装 Preference
标记,如下所示:
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> <PreferenceCategory app:key="notifications_category" app:title="Notifications"> <SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/> </PreferenceCategory> <PreferenceCategory app:key="help_category" app:title="Help"> <Preference app:key="feedback" app:summary="Report technical issues or suggest new features" app:title="Send feedback"/> </PreferenceCategory> </PreferenceScreen>
结果如下所示:
![显示偏好设置和类别的图片](https://developer.android.google.cn/static/develop/ui/views/components/settings/images/settings-preferencecategory.png?authuser=5&hl=ru)
将层次结构拆分为多个屏幕
如果您有大量的 Preference
对象或不同的类别,可以将它们显示在不同的屏幕上。每个屏幕都是一个 PreferenceFragmentCompat
,拥有自己的独立层次结构。然后,初始屏幕上的 Preference
对象可关联到包含相关偏好设置的子屏幕。
图 2 显示了一个简单的层次结构,它包含两个类别:“Messages”和“Sync”。
![一张图片,显示了带有层次结构的偏好设置屏幕](https://developer.android.google.cn/static/develop/ui/views/components/settings/images/settings-simplehierarchy.png?authuser=5&hl=ru)
图 3 显示了拆分为多个屏幕的同一组偏好设置:
![图片显示层次结构拆分为多个屏幕](https://developer.android.google.cn/static/develop/ui/views/components/settings/images/settings-screens.png?authuser=5&hl=ru)
如需关联带有 Preference
的屏幕,您可以在 XML 中声明 app:fragment
,也可以使用 Preference.setFragment()
。点按 Preference
时启动 PreferenceFragmentCompat
的完整软件包名称,如以下示例所示:
<Preference app:fragment="com.example.SyncFragment" .../>
当用户点按带有关联 Fragment
的 Preference
时,系统会调用接口方法 PreferenceFragmentCompat.OnPreferenceStartFragmentCallback.onPreferenceStartFragment()
。此方法用于处理新屏幕的显示,以及在周围的 Activity
中实现屏幕。
典型实现一般如下所示:
Kotlin
class MyActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { ... override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean { // Instantiate the new Fragment. val args = pref.extras val fragment = supportFragmentManager.fragmentFactory.instantiate( classLoader, pref.fragment) fragment.arguments = args fragment.setTargetFragment(caller, 0) // Replace the existing Fragment with the new Fragment. supportFragmentManager.beginTransaction() .replace(R.id.settings_container, fragment) .addToBackStack(null) .commit() return true } }
Java
public class MyActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { ... @Override public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) { // Instantiate the new Fragment. final Bundle args = pref.getExtras(); final Fragment fragment = getSupportFragmentManager().getFragmentFactory().instantiate( getClassLoader(), pref.getFragment()); fragment.setArguments(args); fragment.setTargetFragment(caller, 0); // Replace the existing Fragment with the new Fragment. getSupportFragmentManager().beginTransaction() .replace(R.id.settings_container, fragment) .addToBackStack(null) .commit(); return true; } }
PreferenceScreens
系统不再支持在同一 XML 资源中使用嵌套的 <PreferenceScreen>
声明嵌套层次结构。请改用嵌套的 Fragment
对象。
使用单独的 activity
相对地,如果您需要深入自定义每个屏幕,或者希望在各个屏幕之间切换时执行完整的 Activity
转换,则可以为每个 PreferenceFragmentCompat
使用单独的 Activity
。这样一来,您就可以全面自定义每个 Activity
及其对应的设置屏幕。对于大多数应用,我们不建议这样做;而应使用 Fragments
(如前所述)。
如需详细了解如何从 Preference
启动 Activity
,请参阅偏好设置操作。