So when we set an onClickListener to, say, a Button, it looks something like this.
private Button myButton = (Button) findViewById(R.id.my_button);
myButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
//do this
}
});
So we're creating a nameless anonymous class when we state new View.OnClickListener... and implementing the OnClickListener interface / and overriding it's onClick method. What I don't understand, is if we have no reference to this anon class, because it's nameless, how does the onClick() method get called? I've only ever implemented an anonymous class to override certain methods in said class, like this:
public class Foo{
public void bar(){
//do something
}
}
Foo foo = new Foo(){
#Override
public void bar(){
//do something else
}
}
This makes perfect sense to me because now, anytime I use the "foo" reference to call the bar() method, that reference will use the overridden version of bar. In the case of the Button, there's no reference to onClick(). I'm beyond confused about this.
If it helps your understanding, you could rewrite to this:
View.OnClickListener listener = new View.OnClickListener(){
#Override
public void onClick(View view){
//do this
}
};
myButton.setOnClickListener(listener);
The button holds the reference after listener goes out of scope, and can call the onClick callback on the held listener object.
What I don't understand, is if we have no reference to this anon class, because it's nameless, how does the onClick() method get called?
myButton is holding onto the instance of the anonymous inner class that you created. myButton, therefore, can call onClick() on it.
The onclick event is called in the button object and this object delegates to your anonymous class onclick with the reference you set.
Related
There are multiple ways to register callbacks when a Button is clicked. If I go by the following way:
public class MainActivity extends Activity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(this, "Hello onCLick", Toast.LENGTH_SHORT).show();
}
}
I don't understand how the method setOnClickListener(this) identifies that it should call onClick() method?
This refers to the activity. Because the Activity implements an OnClickListener calling button.setOnClickListener(this) gives the onClickListener that the Activity implements to setOnClickListener.
I recommend you look up info about implementing interfaces in Java if you want tot know more about this practise.
if you are aware about oops 'this' refer the reference of current object of class. a good explanation is define here
In above case MainActivity reference is refer as this here.
public void setOnClickListener(OnClickListener l)
is setter method define in class Button which hold the reference on "OnClickListener".
when you set setOnClickListener(this) it define you are passing OnClickListener reference as your activity so to make your activity as type on OnClickListener you have to implement the interface OnClickListener in your activity class as it is showing in your code.
public class MainActivity extends Activity implements OnClickListener
Its a callback listener which have method "onClick" you have to override that method
and when button is clicked that method is call by Button class so the event listener (which is you activity in current scenario) can listen to it.
I think I understand your confusion. When you read other SO answers or references like the View.OnClickListener, it feels like all the sentences are telling the same thing but nothing that really helps click.
What happens is, when a Button is clicked, it will notify all the objects that are listenning for it. You are subscribing your activity as a listener, to this event with the line
button.setOnClickListener(this);
So, on an event of a click, button knows that it should call the activity's onClick event.
I don't understand how the method setOnClickListener(this) identifies
that it should call onClick() method?
(Therefore, it s the button that calls the listener.onClick() method, in case there's a confusion there.)
Also, #nourikhalass has a point, you should first make sure that interfaces make sense to you.
Is it any clearer?
Your code has
MainActivity implements OnClickListener
but actually it is:
MainActivity implements View.OnClickListener
Maybe that is what confuses you.
"This" refers to current object.
To handle button clicks, an object must implement the "OnClickListener" interface and define what to do when clicks are received in "onClick" method. Then you can register that object as a listener for your button clicks.
In your case, your activity implements OnClickListener, and onClick shows a toast:
public class MainActivity extends Activity implements OnClickListener {
...
#Override
public void onClick(View v) {
Toast.makeText(this, "Hello onCLick", Toast.LENGTH_SHORT).show();
}
Therefore, your activity can handle button clicks, so you register it as a listener for your button:
button.setOnClickListener(this);
As "this" implements the required interface, is a valid listener.
May anyone explain to me this bit of code?
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
startActivity(intent);
}
});
In this case, MainActivity and DetailActivity are two classes I have created.
I am kind of confused,
In this case, what are the roles of setOnClickListener and View.OnClickListener?
Within the constructor method of the Intent class, for the context, why can't we just put ".this" but we have to put in MainActivity class in the front? Under what kind of situation can we use ".this"?
setOnClickListener is a method. View.OnClickListener is an interface. The setOnClickListener method takes a View.OnClickListener as an argument. The syntax new Foo() { ... } defines an anonymous inner class instance that implements the interface Foo.
this refers to the instance, which in case of an inner class is the inner class View.OnClickListener instance. You can refer to the outer class instance (an activity which is-a Context) by scoping the reference with the outer class name.
You have to put MainActivity.this because the setOnClickListener is a interface in a View class and it contains a method onClick(View v); , if you will use this instead of MainActivity.this, it will refer to the Context of OnClickListener, when we specify MainActiviy.this it refers to the Context of MainActivity class. This concept is called Shadowing in java.
I have trouble understanding this code. I get that findViewById will get the button widget and then it'll cast it. Then, it's going to use the button to call the setOnClickListener method. However, I don't know what is that argument being passed into the setOnClickListener and I have never seen code like that before. How is it that it creates a new object but is able to create a method of its own within another method's argument? Would be great if someone could explain that. Also, what type of object is the setOnClickListener method taking in?
btn = (Button)findViewById(R.id.firstButton);
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
tv.setText(months[rand.nextInt(12)]);
tv.setTextColor(Color.rgb(rand.nextInt(255)+1, rand.nextInt(255)+1, rand.nextInt(255)+1));
}
});
It works like this. View.OnClickListenere is defined -
public interface OnClickListener {
void onClick(View v);
}
As far as we know you cannot instantiate an object OnClickListener, as it doesn't have a method implemented. So there are two ways you can go by - you can implement this interface which will override onClick method like this:
public class MyListener implements View.OnClickListener {
#Override
public void onClick (View v) {
// your code here;
}
}
But it's tedious to do it each time as you want to set a click listener. So in order to avoid this you can provide the implementation for the method on spot, just like in an example you gave.
setOnClickListener takes View.OnClickListener as its parameter.
This is the best way to implement Onclicklistener for many buttons in a row
implement View.onclicklistener.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
This is a button in the MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_submit = (Button) findViewById(R.id.submit);
bt_submit.setOnClickListener(this);
}
This is an override method
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.submit:
//action
break;
case R.id.secondbutton:
//action
break;
}
}
That what manual says about setOnClickListener method is:
public void setOnClickListener (View.OnClickListener l)
Added in API level 1 Register a callback to be invoked when this view
is clicked. If this view is not clickable, it becomes clickable.
Parameters
l View.OnClickListener: The callback that will run
And normally you have to use it like this
public class ExampleActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedValues) {
...
Button button = (Button)findViewById(R.id.corky);
button.setOnClickListener(this);
}
// Implement the OnClickListener callback
public void onClick(View v) {
// do something when the button is clicked
}
...
}
Take a look at this lesson as well Building a Simple Calculator using Android Studio.
its an implementation of anonymouse class object creation to give ease of writing less code and to save time
It works by same principle of anonymous inner class where we can instantiate an interface without actually defining a class :
Ref: https://www.geeksforgeeks.org/anonymous-inner-class-java/
I'm working on eclipse (android) and I want to call outside a variable that is in the OnClick method. How can I do that? I thought to use a return but OnClick is a void method. Here is my code
backgroundE2.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
int randomIntE = random2.nextInt(Deck.length());
int drawableIDE = Deck.getResourceId(randomIntE, -1);
backgroundE2.setBackgroundResource(drawableIDE);
}
});
I'm trying to call the variable randomIntE. How can I do that if everything is closed? I have to call also other 4 variables that are in different setOnClickListener.
You can use a global variable declared outside the function.
public class MainActivity extends Activity {
int fnsetFlag= 0;
backgroundE2.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
fnsetFlag= 1;
}
});
}
you should save it somewhere, like in an instance variable or in an object that can be called from the piece of code you want to use.
I hope to have understand the question properly.
Andrea.
I'm trying to understand what is View.OnClickListener().
I have read this site: http://developer.android.com/reference/android/view/View.html, but I cannot understand who is the client and who is the listener.
Please explain in details. Thanks in advance.
From docs:
Interface definition for a callback to be invoked when a view is
clicked.
reference
Simply said: So when you implement this, you are able to handle click events for your Views - all widgets as Button, ImageView etc..
When you implement this you have to implement onClick method. When you click on some View, this method is immediately called.
public void onClick(View v) {
switch(v.getId()) {
// do your work
}
}
But don't forget that you have to register your OnClickListener for specific widget
someButton.setOnClickListener(this);
Most likely you need to learn Android basics and i recommend it to you.
Note: You can use Listeners also as anonymous classes
This is an Interface to implement for classes which want to get a notification if a View element got clicked.
For instance:
public class FooActivity extends Activity implements View.OnClickListener {
public void onCreate(...) {
View v = findViewById(...);
v.setOnClickListener(this);
}
public void onClick(View v) {
// method which is invoked when the specific view was clicked
}
}