20

我正在构建一个首选项活动,其中列表中的大多数首选项将执行代码而不是直接修改 SharedPreference。我的preferences.xml 文件看起来像这样。

<PreferenceCategory
    android:title="Connection" >

    <Preference
        android:id="@+id/settings_connectToNewComputer"
        android:key="connectToNewComputer"
        android:summary="Currently connected to:"
        android:title="Connect to new computer" />

    <Preference
        android:id="@+id/removeDevice"
        android:key="removeDevice"
        android:summary="Remove this device from the computer's whitelist"
        android:title="Remove this device from computer" />

</PreferenceCategory>

<PreferenceCategory
    android:title="About" >

    <Preference
        android:id="@+id/settings_About"
        android:key="about"
        android:summary="About me and my thanks to those who made this app great"
        android:title="About Hue Pro" />

    <Preference
        android:id="@+id/contact"
        android:key="contact"
        android:summary="Contact me with comments, bugs, and suggestions for updates"
        android:title="Contact me" />

</PreferenceCategory>

我的目标是在单击其中一个首选项时执行一段代码。类似于 Google Play 设置偏好菜单中的“清除搜索历史”。( http://i.imgur.com/qnHbJX9.png )

有谁知道如何使这成为可能?

我必须补充一点,我尝试过使用 findPreference("KeyNameHere") 但它总是返回 null。

谢谢!


编辑:

我在这段代码中添加并实现了 OnPreferenceClickListener:

@Override
public boolean onPreferenceClick(Preference preference) {
    return false;
}

但是这个方法永远不会被调用。还有另一种方法可以做到这一点吗?


编辑2:

我发现如果我取出 PreferenceCategory 标签,那么我就剩下这个了:

<Preference
    android:id="@+id/settings_connectToNewComputer"
    android:key="connectToNewComputer"
    android:summary="Currently connected to:"
    android:title="Connect to new computer" />

<Preference
    android:id="@+id/removeDevice"
    android:key="removeDevice"
    android:summary="Remove this device from the computer's whitelist"
    android:title="Remove this device from computer" />

<Preference
    android:id="@+id/settings_About"
    android:key="about"
    android:summary="About me and my thanks to those who made this app great"
    android:title="About Hue Pro" />

<Preference
    android:id="@+id/contact"
    android:key="contact"
    android:summary="Contact me with comments, bugs, and suggestions for updates"
    android:title="Contact me" />

并称之为:

getPreferenceScreen().setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {

        @Override
        public boolean onPreferenceClick(Preference preference) {
            return false;
        }
    });

然后我实际上得到了点击事件的响应。唯一的缺点是我必须删除首选项分组。任何人都知道这是为什么以及任何解决方法?

4

7 回答 7

17

实施OnPreferenceClickListener并在onPreferenceClick

@Override
public boolean onPreferenceClick (Preference preference)
{
    String key = preference.getKey();
    // do what ever you want with this key
}
于 2013-03-21T00:01:19.093 回答
16

也许这对 OP 没有用,但对其他人可能有用。我想写一个总结;一般来说,您可以主要遵循三种方式:1)您可以在代码中的某处找到您的偏好

Preference examplePreference = findPreference(KEY_EXAMPLE_PREFERENCE);

然后你可以添加一个点击监听器并覆盖它的点击方法

examplePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
    @Override
    public boolean onPreferenceClick(Preference preference) {
        // handle click here
    }
});

这必须为您想要收听其点击的每个首选项完成 2)您可以在设置片段/活动中实现 Preference.OnPreferenceClickListener 接口并仅覆盖一次 onPreferenceClick,方法是使用 switch 构造或 if-else if-else if -...构造和合并所有单一的处理;它应该是这样的:

@Override
public boolean onPreferenceClick(Preference preference) {
    switch (preference.getKey()) {
        case KEY_EXAMPLE_PREFERENCE: {
            // handle click here
        }
        break;
        case ...
    }
}

然后,您仍然需要找到每个偏好,但您可以简单地调用它们中的每一个

setOnPreferenceClickListener(this);

(我认为 OP 的实现不起作用(由于最后一部分,他的方法没有被调用))我们将“this”作为参数传递,因为我们实现了点击侦听器接口

3)(我认为是最简单的)你可以覆盖

onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)

在您的偏好片段/活动中而不实现任何其他接口,您可以在那里复制选项 2) 的 if-else if-... 构造的开关;主要优点在于您不需要找到每个首选项并调用它们 setOnPreferenceClickListener。

希望这对某人有用!

于 2014-07-17T16:02:18.890 回答
13

只需覆盖:

@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {

    String key = preference.getKey();
    ...

    return super.onPreferenceTreeClick(preferenceScreen, preference);
}
于 2014-10-28T12:46:13.913 回答
10

您还可以找到首选项并设置点击侦听器。

Preference connectToNewComputer= findPreference("connectToNewComputer");
connectToNewComputer.setOnPreferenceClickListener(this);
于 2013-10-03T19:42:22.810 回答
8

我想出了自己的(我认为真的搞砸了)解决方案;但它有效。

for(int x = 0; x < getPreferenceScreen().getPreferenceCount(); x++){
        PreferenceCategory lol = (PreferenceCategory) getPreferenceScreen().getPreference(x);
        for(int y = 0; y < lol.getPreferenceCount(); y++){
            Preference pref = lol.getPreference(y);
            pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener(){

                @Override
                public boolean onPreferenceClick(Preference preference) {
                    return false;
                }

            });
        }
    }

所以我了解到有一个分层系统,其工作方式如下: PreferenceScreen 有子项 PreferenceCategory 有子项 Preference,正如您在 XML 文件中看到的那样。我的问题是我无法直接从 PreferenceScreen 设置首选项的 onClickListeners。因此,我制作了两个 for 循环,它们将深入到每个 Preference 并为每个循环设置一个 OnPreferenceClickListener。凌乱,但最终工作。

于 2013-03-21T03:31:45.697 回答
7

适用于 2020 年 2 月的 Androidx

其他答案对我来说在Androidx中不起作用。我实现了Android 开发者指南中的设置

请参阅以下指南以实现点击侦听器

1)在您的设置片段中实现PreferenceManager.OnPreferenceTreeClickListener ,如下面的代码

import androidx.preference.PreferenceManager;

class SettingsFragment extends PreferenceFragmentCompat implements PreferenceManager.OnPreferenceTreeClickListener {

2) 在 SettingsFragment 中覆盖 onPreferenceTreeClick

@Override
public boolean onPreferenceTreeClick(Preference preference) {        
    String key = preference.getKey();

        switch (key) {
            case "key1":
                return true;

            case "key2":
                return true;

            //codes    
        }
}
于 2020-02-01T17:20:38.990 回答
0

如果您发现以下内容(从项目中复制粘贴),您的 Preference 对象将不会为 null:

public class ImePreferences extends PreferenceActivity {

......

@Override
protected boolean isValidFragment(String fragmentName) {
    return Settings.class.getName().equals(fragmentName);
}

......

public static class Settings extends InputMethodSettingsFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setInputMethodSettingsCategoryTitle(R.string.language_selection_title);
        setSubtypeEnablerTitle(R.string.select_language);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.ime_preferences);
        Preference pLcl = getPreferenceScreen().findPreference(getResources().getString(
                R.string.dictionary_button));
        pLcl.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                // handle click here
                l.a("this is the click");
                return true;
            }
        });
        if(pLcl != null)
            l.a(6576);
    }
}

......

}
于 2015-08-23T23:58:12.537 回答