Android- Logic behind setOnClickListener - java

I am new to Java/Android programming and unfortunately I don't fully under stand the logic behind this piece of code:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
}
});
I have alredy read a whole lot of tutorials about it but unfortunately in no one so far the code gets explained in detail. Maybe because it's so basic that every decent object oriented programmer would understand the reason for the structure right away.
I am wondering why do I need to use new View.OnClickListener()as a parameter? for the setOnClickListener method. In other words why doesn't something like
button.setOnClickListener(
public void onClick(View v) {
// Perform action on click
});
this work?
Besides that I am not quite sure why the onClick method requires the paramterer of View v.
I would be quite thankful for some help since I am currently rather puzzled.

View.OnClickListener is an interface which you need to implement when you want to handle click events. In your code, you are doing that by doing new View.OnClickListener(). Here you are actually creating an anonymous class that implements View.OnClickListener. And any class that implements View.OnClickListener must also implement all the methods declared in it (e.g. the onClick method). Also, in public void onClick(View v) {..},
the View v denotes the view or the button that was clicked so that you can perform whatever you want with it. For example, get it's id, change it's color etc.

Ok so first of all onClick method wants a parameter as a function. The thing is in Java you can't send a function as a parameter as you can do in other languages (like C++). The Java solution is to use a Functional Interface.
In this case OnClickListener is an interface that have one method you must implement : public void onClick(View v). View v it's the view you just clicked so the method it's called.
button.setOnClickListener(OnClickListener) means the set... function needs an argument that implements the OnClickListener.
So that what this code does :
new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
}
});
It is creating an anonymous class that implements the OnClickListener interface required.

Imagine the case where it would be like what you defined - you do not pass in a parameter and simply describe the actions to be taken when that button is pressed. It will work perfectly but for that button only. You will have to redo this method for every other button. What in the case where there are quite a few buttons that do the same thing? You will end up redefining it every time. Wouldn't it be easier to simply just do it once and then pass that in? Also wouldn't it be easier to simply just have one onClick() method which identifies the id of the element being clicked and then performs the logic just for the widget with that id rather than having laborious separate lines of code?
Also don't forget that the parameter being passed belongs to the View class which is the superclass of every other widget. So you can pass the onClickListener() method defined for other widgets into this method if you want (though this case is practically rare).
To answer your question, the Android team could have designed it to be the way you described but chose to do it this way due to best practices and programming paradignms.

Related

Why do android run methods like "onItemSelected" even if they are not called in the oncreate Method?

Hello everyone i begin to learn Android development and i do not Unterstand how it works.
I understood that there is not a main. Instead it is the android lifecyle. But now i do not Unterstand why methods like "onItemSelected" or "onTouchEvent" executes by android even if tbis methods do not called.
Tahir!
These methods are listeners, so they are listening to the special action you make. They will be called every time you select the item or touch a UI stuff you are listening to. For example, there is a method called setOnClickListener which listens every time you click on something, e.g. any button you have. The syntaxis will be like:
final Button button = (Button) findViewById(R.id.my_cool_button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// your handler code here
}
});
It will be called on touch your button no matter where it is.

Android Studio Event Listener mysteries (to me) (setOnClickEventListener)

I am trying to learn android programming and I am stuck at one point, in terms of deeply understanding the concept.
So there is this code which listens the click event for a view (a button). Code is from a site by the way, and working just fine. But I am obsessed with understanding it to the nuts and bolts.
clearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do some stuff
}
});
I have questions in some different levels:
1. So the parent function (clearButton.setOnClickListener) is the event handler, as far as I can tell, which is trigerred when the button is clicked. And yet we are passing it an object's method, which, as far as I can tell, another event listener. Both of them are named as "ClickListener" so I am confused. Are two of them really event listeners?
2. Where did the View object (one which passed as the callback) came from? Is it implicitly created by the system? I have no such definition in my MainActivity.java file.
3. I clumsly tried to write it with parent function invoking another simple function which just displays an AlertDialog, but I was badly failed, since clearButton.setOnClickEventListener expects a View to be returned from callback (I think:)). Is there any other way to accomplish it or this is the only way setting an event listener to a view? Do I have to accept it the way it is and embrace it, instead of struggling with it :) I ask this only to understand the logic of the structure, code works just fine.
4. What is the view passed to the View.OnClickListener function? Is it the current view (I doubt it is)? What is the use case of the view passed to the View.
5. Where can I (or can I) review the code of the View.OnClickListener function to better understand it?
6. All this exercise trigerred another question in my mind about callbacks, but it is probably subject of another question altogether :)
It's a little bit hard to explain, but you are passing what you can treat as a function.
View is included in the Android Framework.
You can also set the onClick listener via the xml. Check this very helpful post.
From how I understand it, it's the view it is tied to. For example, it is an onClickListener for a button1, the view is referring to button1.
View.OnClickListener
...Okay. I think it would be good for you to go through tutorials first (I suggest udacity :D )
Not very definitive, but I hope this gives you an idea somehow. Happy Learning and Coding! Cheers! :D

Java, Android passing params to method

I'm working through the android developer tutorial and we're now creating a method to match to the method name we gave to android:onClick="sendMessage".
Here's the method:
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
// Do something in response to button
}
The text says this about the method:
In order for the system to match this method to the method name given to android:onClick, the signature must be exactly as shown. Specifically, the method must:
Be public
Have a void return value
Have a View as the only parameter (this will be the View that was clicked)
I understand why it must be public and why the return value is void, but why does the method take (View view) instead of just (view)? I'm coming from a Ruby background so the syntax is confusing me. Why do we pass parameters like this?
why does the method take (View view) instead of just (view)?
View means it is a class and view is just a variable adding those 2 is making the view variable an object of View class that can call all of its method.
This is due to the fact that onClick() method in the OnClickListener Interface which requires a parameter of type View. When you remove the parameter, Android will still attempt to call method sendMessage(View view) but that method does not exist any more, therefore you get error and app will force close.
Parameter view is the actual View (Button in your case) that was clicked. With this, you can assign multiple buttons to invoke the same method and inside the method check which button was clicked.
For more information, see this LINK

Detecting events inside a class [duplicate]

I have a custom View class that extends Spinner. I'm trying to figure out what the correct way to talk to the Activity that it's embedded in is, when the user makes a selection. I see that the OnItemSelected listener gets a reference to the Adapter, but I'm not clear on whether or not I should be using this adapter and walking up its parent chain somehow, or if I should just talk directly to the context (for some reason that doesn't feel safe, even though I can't think of a way in which it might fail, offhand).
the right way to do that, is to "listen" to your custom view by exposing an interface which your view holding a reference to instance of him, and you hosting activity should implement. exactly like the OnItemSelected interface and any events which android views are exposing is been implemented. this is the observer design pattern.
for example:
public class MyCustomSpinner extends Spinner {
public MyCustomSpinner(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public interface IMyEventListener {
public void onEventOccurred();
}
private IMyEventListener mEventListener;
public void setEventListener(IMyEventListener mEventListener) {
this.mEventListener = mEventListener;
}
protected void someMethodWhichDoingSomthingAndShouldRaiseAlsoTheEvent() {
/*
* Some Code which the function doing //more code...
*/
if (mEventListener != null) {
mEventListener.onEventOccurred();
}
}
}
this is how you will use it from your activity:
mMyCustomSpinner.setEventListener(new IMyEventListener() {
#Override
public void onEventOccurred() {
// TODO Auto-generated method stub
}
});
I'm trying to figure out what the correct way to talk to the Activity that it's embedded in is, when the user makes a selection.
You don't want to "talk to the Activity that it's embedded in". You want to talk to the controller responsible for the View. Today, that might be an Activity. Tomorrow, that might be a Fragment.
I see that the OnItemSelected listener gets a reference to the Adapter, but I'm not clear on whether or not I should be using this adapter and walking up its parent chain somehow
That implies that the View knows the specific type of Adapter, since the Adapter interface does not have any sort of getContext() method. Moreover, it ties you to talking to the Activity, which is not a good plan at this point, as mentioned above.
Personally, I'm a bit dubious about having a custom Spinner subclass in the first place. But, assuming there's a good reason for it, you should follow Tal Kanel's advice (posted while I was writing this) and design a custom listener interface for this custom event that is being declared by your custom View. Have the controller (Activity or Fragment) supply an implementation of that interface -- this could be directly implemented on the controller, or implemented as an anonymous inner class (as in Tal Kanel's answer), etc. Have your custom View call method(s) on the listener interface as needed.
The correct way is using a listener of some sort. I think you can make direct reference, your code would just not be reusable for another project then...
A simple solution -
((ParentClass) context).functionToRun();
Where ParentClass is the class name of the activity.

View.OnClickListener, method or class?

sorry if this question is stupid, but I can't wrap my head around Java syntax..I learnt C/C++
I know View is a class which is good..but I don't understand if View.OnClickListener() is a method.
I doubt it unless it returns an object?
I think View is a class which has a static OnClickListener member object..again that doesn't make sense to me..
Can some explain what is happening with this line of code?
button1 = (Button) findByView(R.id.button1) ;
button1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
}
}
So what is happening with this code?
Button1 is a reference to the button1 object in the xml file.
button1 object has a member object setOnClickListener which I from its name I assume initializes an event to the button or something. But it receives View.OnClicListener() object.
I am confused by that..onClick receives a View object so onClickListener is not an object returns a View object?? I don't get it at all.
Can someone explain what happens in that line View.onClickListener() is it another way of saying new this?
View.OnClickListener is an interface, you don't call it, but creates a new instance of it (new View.OnClickListener() is a call to the constructor)
The instance you create is of anonymous class that implements View.OnClickListener, in the brackets right under new View.OnClickListener()
Any class that implements View.OnClickListener must implement the methods declared in it (e.g. onClick)
setOnClickListener just saves the reference to the View.OnClickListener instance you supplied, and when someone clicks the button, the onClick method of the listener you set is getting called.
OnClickListener is an interface. An interface provides a set of Methods other classes can implement. http://download.oracle.com/javase/tutorial/java/concepts/interface.html
You could have another class (Like and adapter), that extends OnClickListener, then your Adapter class could add the method "OnClick(View v)", and it would also be able to handle Click events. Or you could use the code you posted, where you just create an anonymous class, that implements OnClickListener.
-Woody
Android code is geared for event based responses. The block of code is as follows:
Find a button that you've added to the active layout, and assign it to a local variable:
button1 = (Button) findByView(R.id.button1);
Set the on click listener for the button. This is a class that will be invoked when the button registers an event. The class is constructed here, it is anonymous as you don't assign it to a variable, but android will keep track of the reference.
Button events are always due to being pressed, so when the button registers that it has been pressed, it will inform the onClickListener class that the even occurred, and pass itself in as the view. The onClickListener is constructed as:
new View.OnClickListener()
{
public void onClick(View v)
{
}
}
That onClick method is used by the listener to handle the event (in this case, a button press). So, you would put the code you would like executed in that method.
To answer your question directly, the onClickListere is an anonymous class that defines the onClick method, which will handle button events.

Categories