Google 致力于为黑人社区推动种族平等。查看具体举措

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

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

查找偏好设置

要访问单独的 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 中将 可见性设置为 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 应该在其“摘要”中显示当前值,以帮助用户更好地了解 的当前状态。例如,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,以在每次点按 时启动新的 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 的 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,当点按 时,此操作会为 onPreferenceClick() 添加回调。例如,如果您有更复杂的逻辑可以用于处理导航,则可以使用监听器导航到另一个 FragmentActivity

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

Kotlin

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

Java

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