android:onClick
Öznitelik belirtildiğinde , Button
örneğin setOnClickListener
dahili 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
.
Button
sınıf, yapıcı çağrılmasıyla sonuçlanan ve tıklama geri arama işleyicisinin üzerinden ayarlanmasını sağlayan View
sınıftan devralınır .View
setOnClickListener
Attrs.xml dosyasında tanımlanan onClick özniteliği, View.java içinde R.styleable.View_onClick
.
İşte kodu, View.java
işin çoğunu setOnClickListener
kendi 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 Reflection
Faaliyetimizde 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 getMethod
Kullanıldığından, yalnızca genel erişim belirleyicisine sahip işlevler aranır. Aksi takdirde IllegalAccessException
istisnayı 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 getMethod
kabul View.class
edilen yöntemi arar .