How to attach GestureDetector to a ListPreference?
Asked Answered
D

3

7

The challenge of attaching a GestureDetector to a ListPreference is 2-fold:

  1. Getting a handle to a ListPreference that's only defined in a preferences.xml (i.e. not instantiated in Java code).
  2. ListPreference is neither a View nor Activity subclass.

Is it possible at all to attach a GestureDetector to a ListPreference?

If so, how would one go about this? Where would I write the code to instantiate GestureDetector and implement the listener?

Desmund answered 19/6, 2013 at 0:23 Comment(2)
Could you please tell me what is the main goal with this implementation - what is the expected result and what the GestureDetector is going to be used for?Averment
@Averment All I want from it at this point is detect a long-press on any item on the list (and of course return the index of the item that was long-pressed).Desmund
A
4

Unless I didn't quite catch the question correctly, the answer is probably simpler than you might think. The source code for ListPreferece teaches that it's little more than a wrapper around an AlertDialog that displays its various options in a ListView. Now, AlertDialog actually allows you to get a handle on the ListView it wraps, which is probably all you need.

In one of the comments you indicated that, at this stage, all you're interested in is detecting a long-press on any item in the list. So rather than answering that by attaching a GestureDetector, I'll simply use an OnItemLongClickListener.

public class ListPreferenceActivity extends PreferenceActivity implements OnPreferenceClickListener {

    private ListPreference mListPreference;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.list_prefs);

        mListPreference = (ListPreference) findPreference("pref_list");
        mListPreference.setOnPreferenceClickListener(this);
    }

    @Override
    public boolean onPreferenceClick(Preference preference) {
        AlertDialog dialog = (AlertDialog) mListPreference.getDialog();
        dialog.getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                Toast.makeText(getApplicationContext(), "Long click on index " + position + ": " 
                        + parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();
                return false;
            }
        });
        return false;
    }

}

The result (which the toast in the long-click displaying):

enter image description here

With a reference to the ListView, you could also attach an OnTouchListener, GestureDetector etc. Up to you to go from here.

Alitta answered 27/6, 2013 at 19:34 Comment(2)
Yes, you caught the question correctly. :-) +1, accepting & rewarding the bonus. Now... is there any chance that the cast to (AlertDialog) will not work in some Android version/flavor/distro/customization?Desmund
@scatmoi: The cast should be safe for anything that extends from DialogPreference, because that enforces its extending classes to build the Dialog using onPrepareDialogBuilder(AlertDialog.Builder builder). I had a quick look, and ListPreference absides this by contract down to at least Android 1.5 (Cupcake). As a matter of fact, ListPreference has hardly changed throughout the years... Anyways, just for sanity, it wouldn't hurt to add an instanceof check before the cast. :)Alitta
F
1

As @TronicZomB suggested, this isn't directly possible.

You can work around this by creating your own ListPreference derived class, getting its view in the inherited onBindDialogView().

Remember however that the latter is tricky because onBindDialogView() is only called if onCreateDialogView() doesn't return null, and this can happen only if you create your own custom view for YourListPreference.

The recommended way to do this is to build a custom Preference.

Once you have done that, you have a reference to YourListPreference's view, which is mandatory for attaching GestureDetector because one of the steps requires setOnTouchListener() on the view.

Fichtean answered 27/6, 2013 at 12:11 Comment(1)
Your method may work but it is too cumbersome. @MH.'s approach is more elegant (but I don't know if it is guaranteed to be compatible with future Android versions).Desmund
S
0

I have set a GestrueDetector to a ScrollView using setOnTouchListener previously and searched for a similar method for ListPreference, however since the ListPreference does not contain such a method, I do not believe this will be possible.

Suasion answered 21/6, 2013 at 13:28 Comment(2)
The crux of the challenge here is that ListPreference is a view, but it isn't defined in a layout XML and thus can't be accessed via findViewById(). Or can it? I am beginning to think that the only way around this is to define & use a subclass of ListPreference, then in its onCreate(), setOnTouchListener() to it.Desmund
You might be able to do a getView().setOnTouchListener(). Not sure how exactly though.Suasion

© 2022 - 2024 — McMap. All rights reserved.