Визначення android:onClickрезультатів атрибута, Buttonнаприклад, setOnClickListenerвнутрішній виклик . Отже, різниці абсолютно немає.
Щоб мати чітке розуміння, давайте подивимося, як onClickатрибут XML обробляється рамкою.
Якщо файл макета завищений, всі представлені в ньому представлення представлені миттєво. У цьому конкретному випадку Buttonекземпляр створюється за допомогою public Button (Context context, AttributeSet attrs, int defStyle)конструктора. Усі атрибути в тезі XML зчитуються з пакета ресурсів і передаються в AttributeSetконструктор.
Buttonклас успадковується від Viewкласу, який призводить Viewдо виклику конструктора, який піклується про встановлення обробника зворотного виклику через setOnClickListener.
Атрибут onClick, визначений у attrs.xml , в View.java згадується як R.styleable.View_onClick.
Ось код, View.javaякий робить більшу частину роботи для вас, зателефонувавши setOnClickListenerсам.
case R.styleable.View_onClick:
if (context.isRestricted()) {
throw new IllegalStateException("The android:onClick attribute cannot "
+ "be used within a restricted context");
}
final String handlerName = a.getString(attr);
if (handlerName != null) {
setOnClickListener(new OnClickListener() {
private Method mHandler;
public void onClick(View v) {
if (mHandler == null) {
try {
mHandler = getContext().getClass().getMethod(handlerName,
View.class);
} catch (NoSuchMethodException e) {
int id = getId();
String idText = id == NO_ID ? "" : " with id '"
+ getContext().getResources().getResourceEntryName(
id) + "'";
throw new IllegalStateException("Could not find a method " +
handlerName + "(View) in the activity "
+ getContext().getClass() + " for onClick handler"
+ " on view " + View.this.getClass() + idText, e);
}
}
try {
mHandler.invoke(getContext(), View.this);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Could not execute non "
+ "public method of the activity", e);
} catch (InvocationTargetException e) {
throw new IllegalStateException("Could not execute "
+ "method of the activity", e);
}
}
});
}
break;
Як бачите, setOnClickListenerдля реєстрації зворотного дзвінка викликається, як ми це робимо в нашому коді. Різниця полягає лише в тому, що він використовується Java Reflectionдля виклику методу зворотного виклику, визначеного в нашій діяльності.
Ось причина проблем, згаданих в інших відповідях:
- Метод зворотного виклику повинен бути загальнодоступним : оскільки
Java Class getMethodвін використовується, шукаються лише функції з загальнодоступним специфікатором доступу. В іншому випадку будьте готові виправити IllegalAccessExceptionвиняток.
- Під час використання кнопки з onClick у фрагменті, зворотний виклик повинен бути визначений у розділі "Активність" :
getContext().getClass().getMethod()виклик обмежує пошук методу поточним контекстом, який є "Активність" у разі "фрагмента". Отже, шукається метод у класі діяльності, а не у класі Fragment.
- Метод зворотного виклику повинен приймати параметр View : оскільки
Java Class getMethodшукає метод, який приймає View.classяк параметр.