androidpreferenceslisteners

Switch Preference - Handling both onPreferenceChange and onPreferenceClick


I've been trying to get a switch preference working in Android whereby I can intercept and handle differently, in certain cases, when they switch it on/off vs when they click the whole preference.

This is what I'm trying to accomplish: User goes into preferences tags are off and no tags are stored (ie: tag preference is empty) User turns on preference for tags, and since no tags are stored currently it launches a tag search activity for user to find the tag. - works fine.

If tag already exists, and they change the state ONLY then update the value as normal. - works fine

Here's my issue: If they click the preference though and they already have a tag saved, don't change the state (regardless if it's enabled or disabled), launch the tag search activity. - this DOESN'T work.

What I've found so far is that in the final scenario above, I get a call to onPreferenceChanged, followed by a call to onPreferenceClicked, followed by a subsequent call to onPreferenceChanged. This seems to be my problem. The first call to onPreferenceChanged causes my listener on my SharedPreferences to be called telling it that it's now enabled.

If I didn't receive the first call to onPreferenceChanged then I wouldn't have an issue.

Here is the relevant parts where I'm setting the listeners

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

Here are the relevant log lines after running it with a saved tag, and clicking the preference.

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).

Solution

  • After searching for hours more I came across a couple posts that will be helpful to others in this situation.

    This one was the solution I opted for given my problem: How do I create one Preference with an EditTextPreference and a Togglebutton?

    It's a very detailed answer and is very helpful in understanding preferences.

    The other post I came across was this one: http://xgouchet.fr/android/index.php?article4/master-on-off-preferences-with-ice-cream-sandwich

    It will give you pretty much the same look and feel as the one above, but requires more work and because of my requirements wouldn't work for me.