整理您的设置   Part of Android Jetpack.

如果设置屏幕庞大繁杂,用户将难以找到自己想要更改的具体设置。 Preference Library 提供以下方法帮助您更好地整理设置屏幕。

Preference 类别

如果单屏上有多个相关的 Preferences,您可以使用 PreferenceCategory 对其进行分组。 PreferenceCategory 显示类别标题,并直观划分类别。

要在 XML 中定义 PreferenceCategory,需要使用 PreferenceCategory 封装 Preference 标签,如下所示:

<androidx.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>

</androidx.preference.PreferenceScreen>
图 1. 类别中的首选项。

将您的层次结构分割为多个屏幕

如果 Preferences 数量较多,或类别区分明显,则可以在多个屏幕上显示。 每个屏幕都应为拥有单独层次结构的 PreferenceFragmentCompat。 然后,初始屏幕上的 Preferences 可关联至含有相关 Preferences 的子屏幕。

图 2 展示了包含两个类别的简单层次结构:信息和同步。

图 2. 包含两个类别的简单层次结构。

图 3 展示了分割至多个屏幕的一组相同的 Preferences

图 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,
                args)
        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(),
                args);
        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

系统不再支持使用嵌套 <PreferenceScreen> 声明相同 XML 资源中的嵌套层次结构。 您应该转而使用嵌套 Fragment 对象。

使用单独活动

或者,如果需要深度自定义每个屏幕,或想要在屏幕间进行完全 Activity 转换,您可以为每个 PreferenceFragmentCompat 使用单独的 Activity。 通过这种操作,您可以完全自定义每个 Activity 及其对应的设置屏幕。 对于大多数应用,不建议使用这种方法,而应使用之前介绍的 Fragments

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