【问题标题】:Preference Activity on Preference Click Listener偏好点击监听器上的偏好活动
【发布时间】:2013-03-10 08:03:59
【问题描述】:

我正在构建一个 Preference Activity,其中列表中的大多数首选项将执行代码,而不是直接修改 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;
        }
    });

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

【问题讨论】:

    标签: android onclicklistener preferenceactivity


    【解决方案1】:

    实现OnPreferenceClickListeneronPreferenceClick

    @Override
    public boolean onPreferenceClick (Preference preference)
    {
        String key = preference.getKey();
        // do what ever you want with this key
    }
    

    【讨论】:

    • 感谢您的快速回复!请参考我在原帖中的第一次编辑。
    • 那你实现了 OnPreferenceClickListener 了吗?
    • 我试图实现它,但我遇到的问题是我永远无法从代码中加载任何 Preference 对象。正如我在原始帖子中所写,findPreference("KeyNameHere") 总是返回 null,所以我找不到实现 OnPreferenceClickListener 的方法。
    • 当你实现 OnPreferenceClickListener 时,方法 onPreferenceClick(Preference preference) 会给出点击的首选项。所以你所要做的就是调用preference.getKey()来获取这个preference的String名称。
    • 根据您的编辑,我明白您现在的意思了。好的,所以我尝试了这个。我在我的类中添加了实现 onPreferenceClickListener 并实现并覆盖了 onPreferenceClick(Preference arg0) 方法。但是当我点击任何首选项时,这个方法永远不会被调用。我不知道为什么......
    【解决方案2】:

    我想出了自己的(我认为这真的是一团糟)的解决方案;但它有效。

    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。凌乱,但最终工作。

    【讨论】:

    • +1 您的解决方案向我暗示了我在应用程序中选择的内容。我创建了一个String 键数组,然后为每个键获取Preference 并设置onPreferenceClick。这是几行代码。谢谢。
    • 虽然这看起来是对的,但所使用的方法已被弃用。如果您有更新的答案,请编辑您的帖子。注意 getPreferenceScreen() 已弃用。谢谢
    【解决方案3】:

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

    Preference connectToNewComputer= findPreference("connectToNewComputer");
    connectToNewComputer.setOnPreferenceClickListener(this);
    

    【讨论】:

      【解决方案4】:

      也许这对 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。

      希望这对某人有用!

      【讨论】:

        【解决方案5】:

        只需覆盖:

        @Override
        public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
        
            String key = preference.getKey();
            ...
        
            return super.onPreferenceTreeClick(preferenceScreen, preference);
        }
        

        【讨论】:

        • 谢谢,这里有真正的答案!
        【解决方案6】:

        如果您发现以下内容,您的 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);
            }
        }
        

        .....

        }
        

        【讨论】:

          【解决方案7】:

          适用于 2020 年 2 月的 Androidx

          其他答案在 Androidx 中对我不起作用。我从Android Developersguides 实现了设置

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

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

          【讨论】:

          • 最近我注意到我的偏好不再起作用了。花了很多时间才发现—— onPreferenceClick 不再被调用,只有覆盖 onPreferenceTreeClick 有帮助。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-22
          • 1970-01-01
          • 2012-11-15
          • 2012-07-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多