I need a getOnClickListener() for Views in Android. This way I can assign a temporary OnClickListener to my Views. I want to use it like this:
private View.
Answer can be sooo easy
OnClickListener ocl = new OnClickListener {
@Override
public void onClick(View view) {
clickableView.performClick();
}
}
Full functionality of onclicklistener except one thing - you can not pass any view as argument into it, clickableView
will be the handler, but in most cases it is enought
you can override the class and declare a onClicklistener for your view and write setter and getter for onClickListener field:
public class SAutoBgButton extends ImageButton {
public View.OnClickListener mOnClickListener;
@Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
mOnClickListener = l;
}
public OnClickListener getmOnClickListener() {
return mOnClickListener;
}
}
You can do this with...REFLECTION. *drum roll*
This route is fraught with peril.
I don't recommend it, as the internal structure of the class can change at any time, but here's how you can do it currently up to Android 4.2.2 if it's truly unavoidable:
/**
* Returns the current View.OnClickListener for the given View
* @param view the View whose click listener to retrieve
* @return the View.OnClickListener attached to the view; null if it could not be retrieved
*/
public View.OnClickListener getOnClickListener(View view) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return getOnClickListenerV14(view);
} else {
return getOnClickListenerV(view);
}
}
//Used for APIs lower than ICS (API 14)
private View.OnClickListener getOnClickListenerV(View view) {
View.OnClickListener retrievedListener = null;
String viewStr = "android.view.View";
Field field;
try {
field = Class.forName(viewStr).getDeclaredField("mOnClickListener");
retrievedListener = (View.OnClickListener) field.get(view);
} catch (NoSuchFieldException ex) {
Log.e("Reflection", "No Such Field.");
} catch (IllegalAccessException ex) {
Log.e("Reflection", "Illegal Access.");
} catch (ClassNotFoundException ex) {
Log.e("Reflection", "Class Not Found.");
}
return retrievedListener;
}
//Used for new ListenerInfo class structure used beginning with API 14 (ICS)
private View.OnClickListener getOnClickListenerV14(View view) {
View.OnClickListener 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("mOnClickListener");
if (clickListenerField != null && listenerInfo != null) {
retrievedListener = (View.OnClickListener) clickListenerField.get(listenerInfo);
}
} catch (NoSuchFieldException ex) {
Log.e("Reflection", "No Such Field.");
} catch (IllegalAccessException ex) {
Log.e("Reflection", "Illegal Access.");
} catch (ClassNotFoundException ex) {
Log.e("Reflection", "Class Not Found.");
}
return retrievedListener;
}
use
oldListener = new view.OnClickListener() {
@Override
public void onClick(View v) {
// some code
v.setOnClickListener(oldListener);
}
});
instead of
oldListener = view.getOnClickListener(); // doesn't exist
getOnClickListener is not any method for View or for Button in Current API's see docs for more details
http://developer.android.com/reference/android/view/View.OnClickListener.html
Niet!
The oldListener in the answers given is in each case being redefined and it's old state or definition is lost regardless of it's name pretending otherwise.
Following this technique: Get current onClickListener of an Android View object the 'old' listener would be set in the abstract class's onClick method and any temporary listener would use setOnClickListener along with a call to super in order to (re)set the old listener when or as appropriate
The temp listener setting code need not know what the 'old' listener is however there still needs to be some form of coordination in order for the author of that or those listeners to make them abstract and use the onClick method to set the on click listener, in short, to follow a protocol.
Exceptionally you might want to bypass the protected or private qualifier of the onclicklistener View member: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/view/View.java#View.0mOnClickListener and then do a little http://www.jguru.com/faq/view.jsp?EID=321191 which will get you the listener.
You might even want to write your own getOnClickListener, or any getter for that matter, that uses the instrospection approach, if of course it actually works :)
:)