Search code examples
androidandroid-preferencespreferenceactivity

How to add a "long click listener" to a Preference?


I have an PreferenceActivity where I would like to add Preferences dynamically.

On a long click, these shall do something, however OnPreferenceClickListener only supports normal clicks, no long clicks.

Is there a way to implement this feature, did I miss something?

Thanks


Solution

  • In the event that the link dies, here is the main body of the post at that link. Note: I did not author anything below.

    The built-in Preference class has a method to receive clicks, onClick, but no method to receive long clicks. In my current project, I actually have a need for this, and found a way to implement it.

    PreferenceActivity is actually a ListActivity, with a special adapter behind the scenes. The usual (not long) clicks are processed by using the usual ListView mechanism, setOnItemClickListener. The code to set this up is in PreferenceScreen:

    public final class PreferenceScreen extends PreferenceGroup implements AdapterView.OnItemClickListener.... {
        public void bind(ListView listView) {
            listView.setOnItemClickListener(this);
            listView.setAdapter(getRootAdapter());
    
            onAttachedToActivity();
        }
    
        public void onItemClick(AdapterView parent, View view, int position, long id) {
            Object item = getRootAdapter().getItem(position);
            if (!(item instanceof Preference)) return;
                         
            final Preference preference = (Preference) item;
            preference.performClick(this);
        }
    }
    

    It would be really easy to subclass PreferenceScreen and override bind to add a long-item-click listener to the list view, except this class is final. Because of this, I ended up adding the following code into my PreferenceActivity subclass:

    public class BlahBlahActivity extends PreferenceActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
     
            addPreferencesFromResource(R.xml.account_options_prefs);
     
            ListView listView = getListView();
            listView.setOnItemLongClickListener(new OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    ListView listView = (ListView) parent;
                    ListAdapter listAdapter = listView.getAdapter();
                    Object obj = listAdapter.getItem(position);
                    if (obj != null && obj instanceof View.OnLongClickListener) {
                        View.OnLongClickListener longListener = (View.OnLongClickListener) obj;
                        return longListener.onLongClick(view);
                    }
                    return false;
                }
            });
        }
    }
    

    Now I can have a Preference subclass that implements View.OnLongClickListener, which is automatically invoked for long clicks:

    public class BlahBlahPreference extends CheckBoxPreference implements View.OnLongClickListener {
        @Override
        public boolean onLongClick(View v) {
            // Do something for long click
            return true;
        }
    }