I realize that a similarly-worded question has been asked before, but this is different. I am pretty new at developing android apps and I have three questions regarding the difference(s) between the android:onclick=""
XML attribute and the setOnClickListener
method.
What are the differences between the two? Is the difference between the two implementations found at compile time or run time or both?
What use cases are favorable to which implementation?
What difference(s) does the use of fragments in Android make in implementation choice?
OnClickListener is an interface, which defines the onClick(View) method. If you have a class which intends to listen for clicks, you should both implement the interface (if not already extending a class that does), and implement this method too. You have to use both; they're not somehow alternatives.
In Android, the OnClickListener() interface has an onClick(View v) method that is called when the view (component) is clicked. The code for a component's functionality is written inside this method, and the listener is set using the setOnClickListener() method.
Using the android:onClick XML attribute where you just use the name of a public method with the signature void name(View v) or by using the setOnClickListener method where you pass an object that implement the OnClickListener interface.
When the user clicks a button, the Button object receives an on-click event. To define the click event handler for a button, add the android:onClick attribute to the <Button> element in your XML layout. The value for this attribute must be the name of the method you want to call in response to a click event.
Difference Between OnClickListener vs OnClick:
Both function the same way, just that one gets set through java code and the other through xml code.
setOnClickListener Code Implementation:
Button btn = (Button) findViewById(R.id.mybutton);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myFancyMethod(v);
}
});
// some more code
public void myFancyMethod(View v) {
// does something very interesting
}
XML Implementation:
<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="myFancyMethod" />
<!-- even more layout elements -->
Performance:
Both are the same in performance. Xml is pre-parsed into binary code while compiling. so there is no over-head in Xml.
Limitation:
android:onClick is for API level 4 onwards, so if you're targeting < 1.6, then you can't use it.
I'm shocked nobody talked about this but be careful, although android:onClick
XML seems to be a convenient way to handle click, the setOnClickListener
implementation do something additional than adding the onClickListener
. Indeed, it put the view property clickable
to true.
While it's might not be a problem on most Android implementations, according to the phone constructor, button is always default to clickable = true but other constructors on some phone model might have a default clickable = false on non Button views.
So setting the XML is not enough, you have to think all the time to add android:clickable="true"
on non button, and if you have a device where the default is clickable = true and you forget even once to put this XML attribute, you won't notice the problem at runtime but will get the feedback on the market when it will be in the hands of your customers !
In addition, we can never be sure about how proguard will obfuscate and rename XML attributes and class method, so not 100% safe that they will never have a bug one day.
So if you never want to have trouble and never think about it, it's better to use setOnClickListener
or libraries like ButterKnife with annotation @OnClick(R.id.button)
Simply:
If you have android:onClick = "someMethod"
in xml, it looks for the public void someMethod
in your Activity class. OnClickListener
is called right from your Activity and it is linked to some particular View
. For example someButton.setOnClickListener
and in the code below is said what has to be done when someButton
is pressed.
Hope it helps :)
As said before: they both are a way to add logic in response to an event, in this case a 'click' event.
I would go for a separation between logic and presentation, just like we do in the HTML/JavaScript world: Leave the XML for presentation and add event listeners by means of code.
There are a couple of reasons why you might want to programmatically set an OnClickListener
. The first is if you ever want to change the behaviour of your button while your app is running. You can point your button at another method entirely, or just disable the button by setting an OnClickListener
that doesn't do anything.
When you define a listener using the onClick
attribute, the view looks for a method with that name only in its host activity. Programmatically setting an OnClickListener
allows you to control a button's behaviour from somewhere other than its host activity. This will become very relevant when we use Fragments
, which are basically mini activities, allowing you to build reusable collections of views with their own lifecycle, which can then be assembled into activities. Fragments always need to use OnClickListeners
to control their buttons, since they're not Activities, and won't be searched for listeners defined in onClick.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With