切换首选项 – 同时处理onPreferenceChange和onPreferenceClick

我一直试图得到一个开关首选项在Android中工作,我可以截取和处理不同,在某些情况下,当他们打开/closures,当他们点击整个首选项。

这是我想要完成的:用户进入首选项标签已closures,没有标签存储(即:标签首选项为空)用户打开标签的首选项,并且由于当前没有标签存储它启动标签search活动供用户find标签。 – 工作正常。

如果标签已经存在,他们只改变状态,然后更新正常的值。 – 工作正常

这是我的问题:如果他们点击首选项,但他们已经保存了一个标签,不要改变状态(无论是启用还是禁用),启动标签search活动。 – 这不起作用。

到目前为止我发现的是,在上面的最后一个场景中,我接到onPreferenceChanged的调用,然后调用onPreferenceClicked,随后调用onPreferenceChanged。 这似乎是我的问题。 第一次调用onPreferenceChanged会导致我的SharedPreferences上的侦听器被调用,告诉它现在已经启用了。

如果我没有收到onPreferenceChanged的第一个电话,那么我不会有问题。

这里是我设置听众的相关部分

SwitchPreference tagPref = (SwitchPreference) findPreference(PreferencesConstants.PREFERENCE_TAG_ENABLED); tagPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { Log.e("BLAH", "onPrefChanged....is it handled by OnClick?" + Boolean.toString(handledByClick)); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); boolean enabled = prefs.getBoolean(PreferencesConstants.PREFERENCE_TAG_ENABLED, false); Log.e("BLAH", "value stored in prefs? " + Boolean.toString(enabled)); if (newValue instanceof Boolean) { enabled = (Boolean) newValue; } Log.e("BLAH", "New value? " + Boolean.toString(enabled)); if (!handledByClick) { if (enabled && (currentTag == null || currentTag.isEmpty())) { Log.e("BLAH", "Enabled and CurrentTag empty!"); Intent intent = new Intent(getActivity(), TagSearchActivity.class); startActivityForResult(intent, 0); return false; // always return false, we'll handle // updating // this value manually. } else { return true; } } Log.e("BLAH", "returning false (AS IN WE HANDLED IT)."); return false; } }); tagPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { handledByClick = true; Log.e("BLAH", "onprefClick"); Intent intent = new Intent(getActivity(), TagSearchActivity.class); startActivityForResult(intent, 0); return true; } }); 

运行保存的标记后,点击相关的日志行。

 01-18 15:55:05.593: E/BLAH(13261): onPrefChanged....is it handled by OnClick?false 01-18 15:55:05.593: E/BLAH(13261): value stored in prefs? true 01-18 15:55:05.593: E/BLAH(13261): New value? false 01-18 15:55:05.613: E/DifferentClass(13261): On Shared Preferences Changed - tagEnabled 01-18 15:55:05.652: E/DifferentClass(13261): disabled TAG in cancelAlarmService 01-18 15:55:05.662: E/AnotherClass(13261): Updating Feed List. Old Size: 33, New Size: 14 01-18 15:55:05.682: E/BLAH(13261): onprefClick 01-18 15:55:05.812: E/BLAH(13261): onPrefChanged....is it handled by OnClick?true 01-18 15:55:05.812: E/BLAH(13261): value stored in prefs? false 01-18 15:55:05.822: E/BLAH(13261): New value? false 01-18 15:55:05.822: E/BLAH(13261): returning false (AS IN WE HANDLED IT). 

Solutions Collecting From Web of "切换首选项 – 同时处理onPreferenceChange和onPreferenceClick"

我现在一直在处理同样的问题,你可以通过两种方式来解决这个问题。

使用每个事件的自定义操作实现switchpreference:

  • 永远坠毁了一些好点。 我试着跟着他们,但对我来说他们没有这样做。 我敢打赌,他们工作,但我需要更多的function更容易的方式。 Xgouchet(第二个链接)使用标题和自定义XML布局,使用自定义的位置和度量(高度,witdth,填充等)。 我需要一个解决scheme,而不用修改自动生成的布局中的Google。

  • 超级简单而强大的方式:实现您自己的SwitchPreference ! 只要让一个类扩展SwitchPreference ,然后像这样实现/覆盖:

     public class AutoUploadSwitchPreference extends SwitchPreference { public AutoUploadSwitchPreference(Context context) { super(context); } public AutoUploadSwitchPreference(Context context, AttributeSet attrs) { super(context, attrs); } public AutoUploadSwitchPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onClick() { //super.onClick(); THIS IS THE IMPORTANT PART! } 

通过重写onClick()和注释/删除super.onClick()使SwitchPreference 不会调用callChangeListener(Object newValue) 。 现在你可以点击首选项,什么也不发生,直到你想要。 (一个会发生的错误是在片段中有多个onPreferenceChange调用)


现在! 为了使事情发生:这是我用过的结构。

  • 创build一个SettingsActivity
    • 在它确保您获取偏好,资源等
  • 在Activity的onCreate()中 – 启动一个PreferenceFragment
    • 这需要是一个扩展PreferenceFragment的自定义类,看看这里如何: PreferenceFragment
  • 在您的自定义片段中,掌握您的自定义首选项。 你可以使用findPreference("custom_switch_key")

    • 在首选项上添加一个OnPreferenceChangeListener
    • 我个人使我的片段实现了侦听器,并将this作为parameter passing。
    • 返回声明很重要。 这是什么使交换机的实际变化。 如果返回true,则开关将变为newValue。 如果你回报错误,它不会。 如果你使用return false; 您可以在switchpreference上使用setChecked(true | false)更改该值。
  • 当实现onPreferenceChange(Preference preference, Object newValue) ,只需按下切换滑块即可添加所需的任何function

  • 点击首选项的function可以通过三种方式完成:
    • 在自定义的SwitchPreference类中进一步实现onClick()
    • 在片段中实现onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)
    • 像你为ChangeListener一样实现一个onPreferenceClickListener

对不起,如果这是一个很长的职位。 这是我的第一个,我已经通过了这么多的stackoverflow页面,没有人是准确的,只是想要得到它的权利;)

我想你是在问一个不存在的function。

但是,由于首选项活动使用listView,因此可以使用一些技巧来定制它并根据需要处理它。

这里有一篇关于自定义的post ,基于这个网站 。 我问的是如何添加listView,但我不知道一个偏好活动实际上使用一个列表视图。

在search了几个小时之后,我遇到了一些对这种情况有帮助的post。

这一个是我select给我的问题的解决scheme: 如何创build一个EditTextPreference和Togglebutton的偏好?

这是一个非常详细的答案,对理解偏好非常有帮助。

我碰到的另一个post是这个: http : //xgouchet.fr/android/index.php?article4/master-on-off-preferences-with-ice-cream-sandwich

它会给你几乎相同的外观和感觉,但需要更多的工作,因为我的要求不会为我工作。