整理你的设置   属于 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>

结果如下所示

An image showing preferences with categories
图1. 类别内的首选项。

将你的层次结构拆分为多个屏幕

如果你有大量的Preference对象或不同的类别,可以将它们显示在单独的屏幕上。每个屏幕都是一个PreferenceFragmentCompat,具有其自身的独立层次结构。然后,初始屏幕上的Preference对象可以链接到包含相关首选项的子屏幕。

图2显示了一个简单的层次结构,其中包含两个类别:**消息**和**同步**。

An image showing a preference screen with hierarchies
图2. 一个包含两个类别的简单层次结构。

图3显示了同一组首选项拆分为多个屏幕

An image showing a hierarchy split into multiple screens
图3. 拆分为多个屏幕的层次结构。

要使用Preference链接屏幕,可以在XML中声明一个app:fragment,或者可以使用Preference.setFragment()。当点击Preference时,启动PreferenceFragmentCompat的完整包名,如下例所示

<Preference
        app:fragment="com.example.SyncFragment"
        .../>

当用户点击具有关联FragmentPreference时,将调用接口方法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

不再支持使用嵌套的&lt;PreferenceScreen&gt;在同一XML资源中声明嵌套层次结构。请改用嵌套的Fragment对象。

使用单独的Activity

或者,如果你需要大量自定义每个屏幕,或者如果你希望在屏幕之间进行完整的Activity转换,则可以使用单独的Activity来表示每个PreferenceFragmentCompat。通过这样做,你可以完全自定义每个Activity及其对应的设置屏幕。对于大多数应用,我们不建议这样做;而是使用前面描述的Fragment

有关从Preference启动Activity的更多信息,请参阅首选项操作