Question

I want to find out if some items (Buttons, EditText etc) has Touch Listeners - and only if there aren't so I want to add my own Listeners (I get the items from another class). Is there a way to detect that?

Was it helpful?

Solution

Thanks to Niko i was able to do what i want. On api >= 15 , i used reflection (using Niko example) to get the field: mListenerInfo, then i used reflection again to get the field mOnTouchListener. now if it's null it means there is no touch listener, otherwise it has. this is a code example (without try catch):

Field field_mListenerInfo = null;
Object originalListener = null;
Object myListenerInfo = null;
Field field_mOnTouchListener = null;

View viewForField = new View(activity); //needed just to get field name
field_mListenerInfo = viewForField.getClass().getDeclaredField("mListenerInfo");
field_mListenerInfo.setAccessible(true);
originalListener = field_mOnTouchListener.get(myListenerInfo );
myListenerInfo = field_mListenerInfo.get(view);
field_mOnTouchListener = myListenerInfo.getClass().getDeclaredField("mOnTouchListener");
field_mOnTouchListener.setAccessible(true);

now if originalListener is null it means there is no touchListner. else, you can actually use this Listener - for example to concat few listeners. If there are no Listeners at all so mListenerInfo will be null. of course you should pack this code with try catch, otherwise it will break if any of your fields is null.

OTHER TIPS

You can get private field of View called mOnTouchListener

Here is how you use reflection: Access to private inherited fields via reflection in Java

Personally, I think that checking the documentation would be your best bet.

After a while of searching for solutions for this problem myself, I've found a solution that works. I hope the attached code helps:

private static View.OnTouchListener getOnTouchListener(View view) {
        View.OnTouchListener retrievedListener = null;
        String viewStr = "android.view.View";
        String lInfoStr = "android.view.View$ListenerInfo";
        try {

            Field listenerField = Class.forName(viewStr).getDeclaredField("mListenerInfo");
            Object listenerInfo = null;

            if (listenerField != null) {
                listenerField.setAccessible(true);
                listenerInfo = listenerField.get(view);
            }

            Field clickListenerField = Class.forName(lInfoStr).getDeclaredField("mOnTouchListener");

            if (clickListenerField != null && listenerInfo != null) {
                clickListenerField.setAccessible(true);
                retrievedListener = (View.OnTouchListener) clickListenerField.get(listenerInfo);
            }
        } catch (NoSuchFieldException ex) {
            Timber.e("getOnTouchListener() No Such Field. %s",ex.getMessage());
        } catch (IllegalAccessException ex) {
            Timber.e("getOnTouchListener() Illegal Access. %s",ex.getMessage());
        } catch (ClassNotFoundException ex) {
            Timber.e("getOnTouchListener() Class Not Found. %s",ex.getMessage());
        }

        return retrievedListener;
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top