自定义您的设置   Android Jetpack 的一部分。

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

查找偏好设置

如需访问单独的 Preference(例如在获取或设置 Preference 值时),请使用 PreferenceFragmentCompat.findPreference()。此方法会在整个层次结构中搜索具有指定键的 Preference

举例来说,假设一个 EditTextPreference 的键为“signature”:

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

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

Kotlin

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

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    EditTextPreference signaturePreference = findPreference("signature");
    // do something with this 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 signaturePreference: EditTextPreference? = findPreference("signature")
        signaturePreference?.isVisible = true
    }
}

Java

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

动态更新摘要

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

使用 SimpleSummaryProvider

ListPreferenceEditTextPreference 包含一个自动将已保存的 Preference 值显示为摘要的简单 SummaryProvider 实现。如果没有保存任何值,则显示为“Not set”。

您可以通过设置 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: EditTextPreference? = findPreference("counting")

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 = findPreference("counting");

if (countingPreference != null) {
    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 摘要现在会显示已保存值的长度,如果不存在已保存的值,则显示“Not set”。

自定义 EditTextPreference 对话框

EditTextPreference 对话框中,您可以通过附加 OnBindEditTextListener 来自定义文本字段行为。系统在向用户显示对话框时会调用此监听器。

例如,您可以自定义对话框以仅接受数字。首先,您需要创建 EditTextPreference

<EditTextPreference
        app:key="number"
        app:title="Numbers only preference"/>

接下来,在 onCreatePreferences() 中新建 OnBindEditTextListener,然后替换 onBindEditText() 以自定义系统向用户显示的 EditText

Kotlin

val numberPreference: EditTextPreference? = findPreference("number")

numberPreference?.setOnBindEditTextListener { editText ->
    editText.inputType = InputType.TYPE_CLASS_NUMBER
}

Java

EditTextPreference numberPreference = findPreference("number");

if (numberPreference != null) {
    numberPreference.setOnBindEditTextListener(
            new EditTextPreference.OnBindEditTextListener() {
                @Override
                public void onBindEditText(@NonNull EditText editText) {
                    editText.setInputType(InputType.TYPE_CLASS_NUMBER);
                }
            });
}

现在,当系统向用户显示对话框时,键盘会以纯数字模式打开,因此用户只能将数字输入到 EditText 中。

偏好设置操作

在点按时,Preference 可产生特定操作。例如,Preference 可以用作指向应用某个单独部分的链接。如需为 Preference 添加操作,您可以直接在 Preference 上设置 Intent,或设置 OnPreferenceClickListener 以实现更具体的逻辑。

设置 Intent

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

您可以使用嵌套 <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 的 extra:

<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;
});