Menentukan android:onClick
hasil atribut Button
misalnya memanggil secara setOnClickListener
internal. Karenanya sama sekali tidak ada perbedaan.
Untuk memiliki pemahaman yang jelas, mari kita lihat bagaimana onClick
atribut XML ditangani oleh framework.
Ketika file tata letak meningkat, semua tampilan yang ditentukan di dalamnya adalah instantiated. Dalam kasus khusus ini, Button
instance dibuat menggunakan public Button (Context context, AttributeSet attrs, int defStyle)
konstruktor. Semua atribut dalam tag XML dibaca dari bundel sumber daya dan diteruskan AttributeSet
ke konstruktor.
Button
kelas diwarisi dari View
kelas yang menghasilkan View
konstruktor dipanggil, yang mengatur pengaturan panggilan balik melalui penelepon setOnClickListener
.
Atribut onClick didefinisikan dalam attrs.xml , disebut dalam View.java sebagai R.styleable.View_onClick
.
Berikut adalah kode View.java
yang berfungsi untuk Anda dengan menelepon setOnClickListener
sendiri.
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;
Seperti yang Anda lihat, setOnClickListener
dipanggil untuk mendaftarkan panggilan balik, seperti yang kita lakukan dalam kode kita. Hanya perbedaan yang digunakannya Java Reflection
untuk memanggil metode panggilan balik yang ditentukan dalam Aktivitas kami.
Berikut adalah alasan untuk masalah yang disebutkan dalam jawaban lain:
- Metode panggilan balik harus umum : Karena
Java Class getMethod
digunakan, hanya fungsi dengan penentu akses publik yang dicari. Kalau tidak siap untuk menangani IllegalAccessException
pengecualian.
- Saat menggunakan Tombol dengan onClick di Fragment, callback harus didefinisikan dalam Activity :
getContext().getClass().getMethod()
call membatasi pencarian metode ke konteks saat ini, yaitu Activity dalam kasus Fragment. Oleh karena itu metode dicari dalam kelas Activity dan bukan kelas Fragment.
- Metode panggilan balik harus menerima parameter Tampilan : Karena
Java Class getMethod
mencari metode yang menerima View.class
parameter.