android:onClick
属性を指定すると、Button
インスタンスがsetOnClickListener
内部的に呼び出されます。したがって、違いはまったくありません。
明確に理解するために、XML onClick
属性がフレームワークによってどのように処理されるかを見てみましょう。
レイアウトファイルがインフレートされると、その中で指定されているすべてのビューがインスタンス化されます。この特定のケースでは、Button
インスタンスはpublic Button (Context context, AttributeSet attrs, int defStyle)
コンストラクタを使用して作成されます。XMLタグ内のすべての属性がリソースバンドルから読み取られAttributeSet
、コンストラクターに渡されます。
Button
クラスがから継承さView
で結果クラスView
を経由して、クリックコールバックハンドラを設定するの面倒を取るコンストラクタが呼び出され、setOnClickListener
。
attrs.xmlで定義されているonClick属性は、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
例外を処理する準備をしてください。
- FragmentのonClickでButtonを使用している間、コールバックはActivity:
getContext().getClass().getMethod()
callで定義する必要があります。メソッド検索を現在のコンテキスト(Fragmentの場合はActivity)に制限します。したがって、メソッドはFragmentクラスではなく、Activityクラス内で検索されます。
- コールバックメソッドはViewパラメータを受け入れる必要があります:パラメータとして
Java Class getMethod
受け入れるメソッドを検索しView.class
ます。