When Android inflates a Button
with an onClick
XML attribute, it internally sets a DeclaredOnClickListener
on that Button
which then uses reflection to trigger the actually onClick
method in our code.
case R.styleable.View_onClick:
[...]
final String handlerName = a.getString(attr);
if (handlerName != null) {
setOnClickListener(new DeclaredOnClickListener(this, handlerName));
}
break;
I noticed that for AppCompatButton
s (i.e. normal Buttons
in an AppCompatActivity
) the same process gets repeated in the AppCompatViewInflater
class, resulting in 2 different DeclaredOnClickListener
s set in succession.
private void checkOnClickListener(View view, AttributeSet attrs) {
Context context = view.getContext();
if (context instanceof ContextWrapper && (VERSION.SDK_INT < 15 || ViewCompat.hasOnClickListeners(view))) {
TypedArray a = context.obtainStyledAttributes(attrs, sOnClickAttrs);
String handlerName = a.getString(0);
if (handlerName != null) {
view.setOnClickListener(new AppCompatViewInflater.DeclaredOnClickListener(view, handlerName));
}
a.recycle();
}
}
Both methods are executed, and both DeclaredOnClickListeners
are created and set on the Button
. First the View
one, which then gets replaced by the AppCompatViewInflater
one. This all happens in the View
inflation process.
Is that a bug? Or what is the purpose of that behavior?
来源:https://stackoverflow.com/questions/56031088/why-does-the-xml-onclick-attribute-set-an-onclicklistener-twice-on-appcompatbutt