Search code examples
androidpreferenceactivity

Can PreferenceActivity customize how it handles touches?


I've been recently introduced to PreferenceActivity and would like to change how I handle interaction with an EditTextPreference defined in the xml.

I've put logs, toast and breakpoints over where boilerplate has overridden onListItemClick( but nothing is getting back to me. I've even tried stepping into the super class and was able to set breakpoints on the if and return successfully although they weren't ultimately trapping.

protected void onListItemClick(ListView l, View v, int position, long id) {
    if (!isResumed()) {
        return;
    }
    super.onListItemClick(l, v, position, id);

Thanks for looking

EDIT @DanielLe, here is my code:

//This isn't getting called?!
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    String selection = l.getItemAtPosition(position).toString();
    Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
    Log.d("Activity", "onListItemClick=" + l.getItemAtPosition(position).toString());
    super.onListItemClick(l, v, position, id);
}

Solution

  • At the risk of repeating what's gone before, one solution is to extend DialogPreferences as described in the Google guide for Android dev. It's only showing ok and cancel buttons which I believe makes it the minimum for a persisting DialogPreferences implementation:

    Android: Creating custom preference

    import android.content.Context;
    import android.content.DialogInterface;
    import android.os.Parcel;
    import android.os.Parcelable;
    import android.preference.DialogPreference;
    import android.preference.EditTextPreference;
    import android.util.AttributeSet;
    import android.widget.Button;
    import android.widget.EditText;
    
    public class ClickablePreference extends DialogPreference {
        private String mNewValue;
        private EditText mEditText;
    
        public ClickablePreference(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            setDialogLayoutResource(R.layout.dir_picker_dialog);
            setPositiveButtonText(android.R.string.ok);
            setNegativeButtonText(android.R.string.cancel);
    
            setDialogIcon(null);
        }
    
        @Override
        protected void onDialogClosed(boolean positiveResult) {
            // When the user selects "OK", persist the new value
            if (positiveResult) {
                persistString(mNewValue);
            }
        }
    
        private static class SavedState extends BaseSavedState {
            // Member that holds the setting's value
            // Change this data type to match the type saved by your Preference
            String value;
    
            public SavedState(Parcelable superState) {
                super(superState);
            }
    
            public SavedState(Parcel source) {
                super(source);
                // Get the current preference's value
                value = source.readString();  // Change this to read the appropriate data type
            }
    
            @Override
            public void writeToParcel(Parcel dest, int flags) {
                super.writeToParcel(dest, flags);
                // Write the preference's value
                dest.writeString(value);  // Change this to write the appropriate data type
            }
    
            // Standard creator object using an instance of this class
            public static final Parcelable.Creator<SavedState> CREATOR =
                    new Parcelable.Creator<SavedState>() {
    
                        public SavedState createFromParcel(Parcel in) {
                            return new SavedState(in);
                        }
    
                        public SavedState[] newArray(int size) {
                            return new SavedState[size];
                        }
                    };
        }
    
        @Override
        protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
            if (restorePersistedValue) {
                // Restore existing state
                mNewValue = this.getPersistedString("");
            } else {
                // Set default state from the XML attribute
                mNewValue = (String) defaultValue;
                persistString(mNewValue);
            }
        }
    
        @Override
        protected Parcelable onSaveInstanceState() {
            final Parcelable superState = super.onSaveInstanceState();
            // Check whether this Preference is persistent (continually saved)
            if (isPersistent()) {
                // No need to save instance state since it's persistent,
                // use superclass state
                return superState;
            }
    
            // Create instance of custom BaseSavedState
            final SavedState myState = new SavedState(superState);
            // Set the state's value with the class member that holds current
            // setting value
            myState.value = mNewValue;
            return myState;
        }
    
        @Override
        protected void onRestoreInstanceState(Parcelable state) {
            // Check whether we saved the state in onSaveInstanceState
            if (state == null || !state.getClass().equals(SavedState.class)) {
                // Didn't save the state, so call superclass
                super.onRestoreInstanceState(state);
                return;
            }
    
            // Cast state to custom BaseSavedState and pass to superclass
            SavedState myState = (SavedState) state;
            super.onRestoreInstanceState(myState.getSuperState());
    
            // Set this Preference's widget to reflect the restored state
            mEditText.setText(myState.value);
        }
    
        @Override
        protected void onClick() {
            super.onClick();
        }
    
        @Override
        public void onClick(DialogInterface dialog, int which) {
            super.onClick(dialog, which);
        }
    }
    

    I've yet to look at Concise way of writing new DialogPreference classes? in detail although it seems very similar to what I got from Google.

    The problem with this solution, apart from its size, is that mEditText is unused and I couldn't actually grab a reference to the displayed EditText defined in xml.


    Roll on Solution 2

    With thanks to Android: launch a custom Preference from a PreferenceActivity

    just tagged this on the end of onPostCreate from MyPreferenceActivity

    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        setupSimplePreferencesScreen();
        Preference customPref = (Preference) findPreference("pref_do_something");
        customPref.setOnPreferenceClickListener(
                new Preference.OnPreferenceClickListener() {
                    public boolean onPreferenceClick(Preference preference) {
                        Log.d("Activity", "onPreferenceClick=" + preference.toString());
                        return true;
                    }
                });
    }
    

    Far better :)