自定义您的设置   Part of Android Jetpack.

本主题将介绍如何在您的层次结构中自定义 Preferences

寻找首选项

要访问单独 Preference(例如在获取或设置 Preference 值时),请使用 PreferenceFragmentCompat.findPreference()。 此方法使用给定密钥搜索整个层次结构,以寻找 Preference

举例而言,给定一个密钥为“signature”的 EditTextPreference

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

我们可以使用以下代码,检索此 Preference

Kotlin

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    val preference = findPreference("signature") as EditTextPreference
    // do something with this preference
}

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    EditTextPreference preference = (EditTextPreference) findPreference("signature");
    // do something with this preference
}

Control Preference 可见性

您可以在用户跳转至设置屏幕时,控制哪些 Preferences 对用户可见。 例如,如果某个特定 Preference 仅在对应功能启用时才有意义,则您可能想在该功能停用时隐藏该 Preference

要仅在符合某项条件时显示 Preference,首先要在 XML 中将 Preference 可见性设置为 false,如以下示例所示:

<EditTextPreference
        app:key="signature"
        app:title="Your signature"
        app:isPreferenceVisible="false"/>

接下来,当符合相应条件时,在 onCreatePreferences() 中显示 Preference

Kotlin

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    if(*/\*some feature\*/*) {
        val preference = findPreference("signature")
        preference.isVisible = true
    }
}

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    if(*/\*some feature\*/*) {
        Preference editTextPreference = findPreference("signature");
        editTextPreference.setVisible(true);
    }
}

动态更新摘要

保留数据的 Preference 应该在其 摘要 中显示当前值,以帮助用户更好地了解 Preference 的当前状态。 例如,EditTextPreference 应显示当前保存的文本值,而 ListPreference 应显示当前选中的列表条目。 您可能还有需要根据内部或外部应用状态更新其摘要内容的 Preferences,例如显示版本号的 Preference。 您可以使用 SummaryProvider 实现此功能。

使用 SimpleSummaryProvider

ListPreferenceEditTextPreference。 包括自动显示已保存的 Preference 值的简单 SummaryProvider 实现。 如果没有保存任何值,则显示为“未设置”。

您可以通过设置 app:useSimpleSummaryProvider="true",从 XML 中启用这些实现。

或者,您也可以通过代码启用,即使用 ListPreference.SimpleSummaryProvider.getInstance()EditTextPreference.SimpleSummaryProvider.getInstance() 获取简单的 SummaryProvider 实例,然后在 Preference 上进行设置,如以下示例所示:

Kotlin

listPreference.summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()

Java

listPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
editTextPreference.setSummaryProvider(EditTextPreference.SimpleSummaryProvider.getInstance());

使用自定义 SummaryProvider

无论 Preference 何时请求摘要,您都可以创建自己的 SummaryProvider,并替换 provideSummary(),以自定义摘要。 例如,下面的 EditTextPreference 展示了其作为摘要保存的值的长度:

举例来说,假设以下 EditTextPreference

<EditTextPreference
        app:key="counting"
        app:title="Counting preference"/>

onCreatePreferences() 中,新建 SummaryProvider,然后替换 provideSummary() 以返回要显示的摘要:

Kotlin

val countingPreference = findPreference("counting") as EditTextPreference

countingPreference.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
    val text = preference.text
    if (TextUtils.isEmpty(text)) {
        "Not set"
    } else {
        "Length of saved value: " + text.length
    }
}

Java

EditTextPreference countingPreference = (EditTextPreference) findPreference("counting");

countingPreference.setSummaryProvider(new SummaryProvider<EditTextPreference>() {
    @Override
    public CharSequence provideSummary(EditTextPreference preference) {
        String text = preference.getText();
        if (TextUtils.isEmpty(text)){
            return "Not set";
        }
        return "Length of saved value: " + text.length();
    }
});

现在,Preference 摘要显示保存的值的长度,如果 不存在保存的值,则显示“未设置”。

首选项操作

Preference 在点按时可执行特定操作。 例如,Preference 可以用作关联应用某个单独部分的链接。 要为 Preference 添加操作,您可以直接在 Preference 上设置 Intent,或设置 OnPreferenceClickListener,以获得更具体的逻辑。

设置 Intent

您可以在 Preference 上设置 Intent,以在每次点按 Preference 时,启用新的 FragmentActivity、或单独的应用。 这等同于使用给定 IntentContext.startActivity()

您可以使用嵌套 <intent> 标签在 XML 中设置 Intent。 下方示例定义了启动 ActivityIntent

<Preference
        app:key=”activity”
        app:title="Launch activity">
    <intent
            android:targetPackage="com.example"
            android:targetClass="com.example.ExampleActivity"/>
</Preference>

或者,您也可以在 Preference 上直接使用 setIntent(),如下所示:

Kotlin

val intent = Intent(context, ExampleActivity::class.java)
activityPreference.setIntent(intent)

Java

Intent intent = new Intent(getContext(), ExampleActivity.class);
activityPreference.setIntent(intent);

您还可以通过 XML,添加带有 Intent 的 extras:

<Preference
        app:key=”activity”
        app:title="Launch activity">
    <intent
            android:targetPackage="com.example"
            android:targetClass="com.example.ExampleActivity">
        <extra
                android:name="example_key"
                android:value="example_value"/>
    </intent>
</Preference>

以下为 Preference 的示例,其中带有启动网页的 Intent

<Preference
        app:key=”webpage”
        app:title="View webpage">
    <intent
            android:action="android.intent.action.VIEW"
            android:data="http://www.google.com" />
</Preference>

Kotlin

val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("http://www.google.com")
webpagePreference.setIntent(intent)

Java

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
webpagePreference.setIntent(intent);

OnPreferenceClickListener

您可以在 Preference 上设置 OnPreferenceClickListener,当点按 Preference 时,此操作会为 onPreferenceClick() 添加回调。 例如,如果您有更复杂的逻辑可以用于处理跳转,则可以使用侦听器跳转至另一个 FragmentActivity

要设置 OnPreferenceClickListener,请使用与下方所示内容类似的代码:

Kotlin

onClickPreference.setOnPreferenceClickListener({
    // do something
    true
})

Java

onClickPreference.setOnPreferenceClickListener(preference -> {
    // do something
    return true;
});