Search code examples
androidpreferences

setOnPreferenceChangeListener not working for custom checkboxpreference


I made a simple extension of CheckBoxPreference so that I could have my own custom view with an image icon to the left of the title. The code is below:

public class CustomCheckBoxPreference extends CheckBoxPreference {

private Drawable icon;

public CustomCheckBoxPreference(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.CustomCheckBoxPreference, 0, 0);
    icon = arr.getDrawable(R.styleable.CustomCheckBoxPreference_icon);
    setLayoutResource(R.layout.custom_checkbox_pref);
}

@Override
protected void onBindView(View view) {
    super.onBindView(view);
    ImageView prefsIcon = (ImageView) view.findViewById(R.id.prefs_icon);
    prefsIcon.setImageDrawable(icon);
}

The problem is that for some reason the OnPreferenceChangeListener I set to any CustomCheckboxPreference has no effect and is not stored. I tried overriding some of the android methods for the implementation calling super and then printing a line to see what gets called. Notably callChangeListener does not get called. It is this method that leads to the callback for onPreferenceChanged. I tried throwing in a call to onPreferenceChanged inside of setChecked just to see what would happen and the OnPreferenceChangeListener is null:

            getOnPreferenceChangeListener().onPreferenceChange(this, checked);

This is how I set the preferencechangelistener:

        mTwitterPref.setChecked(!mTwitter.needsAuth());
    mTwitterPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            System.out.println("Twitter Preference Changed!");
            if ((Boolean) newValue) {
                if (mTwitter.needsAuth()) {
                    System.out.println("We Need To Login To Twitter!");
                    IntentUtils.startActivityForResult(ProfileAccountsActivity.this,
                            TwLoginActivity.class, ACTIVITY_OAUTH);
                }
            } else {
              showDialog(DIALOG_LOGOUT_TWITTER);
            }
            return false;
        }
    });

I am a bit confused as to why the preferencechangelistener is not working properly as I only overwrite onBindView and the constructor; I call super in both. Any thoughts?


Solution

  • Set android:focusable="false" and android:clickable="false" on the CheckBox:

    <CheckBox
        android:id="@+android:id/checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:focusable="false"
        android:clickable="false" />
    

    More info on this thread: Clickable rows on custom ArrayAdapter