android:onClickÖznitelik belirtildiğinde , Buttonörneğin setOnClickListenerdahili olarak arama yapılır . Dolayısıyla kesinlikle hiçbir fark yoktur.
Açık bir anlayışa sahip olmak için, XML onClicközelliğinin çerçeve tarafından nasıl ele alındığını görelim .
Bir düzen dosyası şişirildiğinde, içinde belirtilen tüm Görünümler somutlaştırılır. Bu özel durumda, Buttonörnek public Button (Context context, AttributeSet attrs, int defStyle)yapıcı kullanılarak oluşturulur. XML etiketindeki tüm öznitelikler kaynak paketinden okunur ve yapıcıya iletilir AttributeSet.
Buttonsınıf, yapıcı çağrılmasıyla sonuçlanan ve tıklama geri arama işleyicisinin üzerinden ayarlanmasını sağlayan Viewsınıftan devralınır .ViewsetOnClickListener
Attrs.xml dosyasında tanımlanan onClick özniteliği, View.java içinde R.styleable.View_onClick.
İşte kodu, View.javaişin çoğunu setOnClickListenerkendi başına arayarak yapar .
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;
Gördüğünüz gibi setOnClickListener, kodumuzda yaptığımız gibi geri aramayı kaydetmek için çağrılır. Tek fark, Java ReflectionFaaliyetimizde tanımlanan geri arama yöntemini çağırmak için kullanılmasıdır.
Diğer yanıtlarda belirtilen sorunların nedeni şunlardır:
- Geri arama yöntemi herkese açık olmalıdır :
Java Class getMethodKullanıldığından, yalnızca genel erişim belirleyicisine sahip işlevler aranır. Aksi takdirde IllegalAccessExceptionistisnayı ele almaya hazır olun .
- OnClick in Fragment ile Düğme kullanılırken, geri çağırma Etkinlik'te tanımlanmalıdır :
getContext().getClass().getMethod()çağrı, yöntem aramasını Parçalanma durumunda Etkinlik olan geçerli bağlamla sınırlar. Bu nedenle yöntem, Fragment sınıfında değil, Activity sınıfında aranır.
- Geri arama yöntemi View parametresini kabul etmelidir : Parametre olarak
Java Class getMethodkabul View.classedilen yöntemi arar .