Why is (this) used in setOnClickListener() - java

Please explain why, in the below code (this) is used as argument to setOnClickListener()? I am new in coding if you could explain the total code I would be thankful.
public class MainActivity extends Appcomatactivity implements
View.OnClickListner {
Textview textview;
Button push_me, push_me2;
protected void onCreate(bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.Layout.activity_main);
textview = (Textview)findViewById(R.Id.Textview);
push_me=(Button)findViewById(R.Id.pushmebutton);
push_me2=(Button)findViewById(R.Id.pushmebutton2);
// Why does below code use (this) as argument?
push_me.setOnClickListener(this);
push_me2.setOnClickListener(this);
}
// <...some activity methods...>
// onclick method defined:
public void onClick(View view) {
switch(view.getid()) {
case R.Id.pushmebutton:
textview.setText("button 1 clicked");
break;
case R.id.pushmebutton2:
textview.setText("button 2 clicked");
break;
}
}
}

Why is (this) used in setonclicklistner
Because your have implemented View.OnClickListener interface to your activity
View.OnClickListener Interface definition for a callback to be invoked when a view is clicked.
By using this push_me.setOnClickListener(this); you have registered click listener to your view

when we don't want to use anonymous class then we use this other way is to use anonymous inner class
//declaring OnClickListener as an object
private OnClickListener btnClick = new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
};
//passing listener object to button
btn1.setOnClickListener(btnClick);
If there are multiple buttons which require same code to be executed on onClick event then you may define listener as an object and pass it to them.

Related

How to use setOnClickListener to the buttons in android using java [duplicate]

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/

Buttons outside the onCreate

Always in my apps I added buttons in void onCreate, but now I'm trying to do app with more buttons (about 10). I would like to all buttons active on start app.
In my opinion it is too much buttons to add in this onCreate and app will be starting to long.
I tried to put this:
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
myMethod();
}
})
out of onCreate
but AndroidStudio underlines setOnClickListener and view
I don't have ideas, how and where can i add button out of onCreate.
If you don't want to overcrowd your oncreate method, then create a clicklistener outside onCreate anywhere in activity and in onCreate just set it.
onCreate :
edit_a_member = (Button) findViewById(R.id.edit_member);
delete_a_member = (Button) findViewById(R.id.delete_member);
edit_a_member.setOnClickListener(handleClick);
delete_a_member.setOnClickListener(handleClick);
clickListener:
private View.OnClickListener handleClick = new View.OnClickListener() {
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.edit_member:
member_selected = EDIT_MEMBER_SELECTED;
callDialog();
break;
case R.id.delete_member:
callDeleteAlert();
break;
}
}
};
You can simply add a separate method for your buttons in the same class, e.g.:
public void onCreate(...){
//Standard setup of views or whatever you want to do here
this.addButtons();
}
private void addButtons(){
Button b1 = new Button("Hi");
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
myMethod();
}
});
Button b2 = new Button("Hi to you too");
b2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
myMethod();
}
});
}
This is an example. You can do this in soooo many ways. I feel like you should thoroughly learn Java's fundamental Object Oriented programming, because that's really what your question suggests you don't understand. Go follow a youtube tutorial. I always like "The New Boston"'s Java tutorial series on youtube.
PS: You can make code like this beautiful under the 'Words of wisdom': Don't repeat yourself
If you have to do a lot of work in your onCreate but you are worried that the UI will take too long to load you can always post a delayed runnable to a handler so in the onCreate method put :
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//add your code here
}
},10);
what this will do is your UI will load then the code in your Runnable will be executed 10 milliseconds after your UI loads thus your app will not take too long to load the UI, even though in your case I doubt it would be necessary.
If you are declaring the buttons in xml file :
Add these properties in each button Declaration in your Xml :
android:clickable="true"
android:onClick="onClick"
And now in Activity Class create a method like this :
public void onClick(View v){
switch(v.getId){
case R.id.{buttons_id_in_xml}
(Your Code)
break;
(Like for others)
}
}
If you want to add buttons dynamically :
Create a method to add the button like this:
void addButton(String buttonName, int button id){
Button button = new Button(this);
button.setText("Push Me");
(add it to parent Layout of xml)
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(id){
case id1:
(handle )
break;
(like for others)
}
}
});
}
The best way to do this is:
add implements View.OnClickListener to
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
// declare variables
private Button mBtn1;
private Button mBtn2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
// make an instance to the btns
mBtn1 = findViewById(R.id.btn1);
mBtn2 = findViewById(R.id.btn2);
// set onClickListener
mBtn1.setOnClickListener(this); // with "this" you are passing the view
mBtn2.setOnClickListener(this);
}
// implement onClick
#Override
public void onClick(View view) {
// check which btn was clicked by id
switch (view.getId()) {
case R.id.btn1:
btn1Clicked();
break;
case R.id.btn2:
btn2Clicked();
break;
}
}
private void btn1Clicked() {
// your code btn1 clicked
}
private void btn2Clicked() {
// your code btn2 clicked
}
Hope this helped. Cheers!

How can I access a method from an activity and use it into another activity in Android?

I have the first class named iHave
public class iHave extends ActionBarActivity
{
//below is the instance for calling the method from the other activity.
(The name of the other activity is **iThank**)
**iThank thankYou = new iThank();**
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_i_have);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
**//this is the method I want to access from iThank class** **strong text**
thankYou.display();
}
});
}
//The Next class is "iThank"
public class iThank extends ActionBarActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_i_thank);
txtThank = (TextView) findViewById(R.id.textView3);
//this is the method I want to access/use from iHave Activity
public void display()
{
txtThank.setText ("Shine");
}
}
How can I use the method "public void display()" of iThank activity to the "iHave" activity? It always gives me an error of NullPointerException. Please help. Thank you very much!
How can I access a method from an activity and use it into another
activity in Android?
By creating object for other to access method from Activity is right way.
Use LocalBroadcastManager for communicating between application components.
1. Send broadcast from iHave on Button click:
#Override
public void onClick(View v)
{
Intent intent = new Intent("DISPLAY_EVENT");
LocalBroadcastManager.getInstance(v.getContext()).sendBroadcast(intent);
}
2. Register LocalBroadcastManager in iThank Activity:
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(ReceiveMessage,
new IntentFilter("DISPLAY_EVENT"));
}
3. Create BroadcastReceiver object and call display() method in iThank Activity:
private BroadcastReceiver ReceiveMessage = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
display();
}
};
Also add null check in display method for TextView:
public void display()
{
if(txtThank !=null)
txtThank.setText ("Shine");
}
Please don't to this, it is not how activities are intended to work. You might want to have a look over the Activities Developer Guide to get started. If you want to launch a new activity (e.g. iThank) from the current foreground activity (e.g. iHave), you never instantiate the class yourself directly and always launch it using an intent. If you have data to pass along (such as a message to display), it needs to be bundled along with the intent as an extra (see same link).
Activities should never call methods on each other directly, because this requires them to have references to each other. The framework manages the life cycle of each activity independently, and those references can lead to leaks.

C and Java how to keep function definitions separate, rather than new OnClickHandler(){

I have a good background in C, and now I am writing code for android/java.
What I fail to understand that why function definition of a handler function is done inside another function. Code becomes so messy and hard to maintain and understand( from a C programmer POV).
So I have this code
final Button btnOpenPopup = (Button)findViewById(R.id.menuButton);
btnOpenPopup.setOnClickListener(new
Button.OnClickListener()
{...}
Is it possible to have a function
myButtonClickListner() {} defined in the class and btnOpenPopup.setOnClickListener((SomeCast)myButtonClickListner
I think there has to be a way, But I am not able to find it..
Please comment.
Well, there are two ways to do this:
1- Have the containing class implement the OnClickListener interface. For example:
public class MainActivity extends Activity implements OnClickListener{
//...
public void onCreate(Bundle savedState){
//...
final Button btnOpenPopup = (Button)findViewById(R.id.menuButton);
btnOpenPopup.setOnClickListener(this);
}
public void onClick(View v){
switch(v.getId()){
case R.id.button1:
//
break;
}
}
2- The second method is the one described by Selvin in his comment: creating a separate class, which implements the OnClickListener interface, and instantiate it in your onCreate(). So, assuming that you have a myButtonListener class in its own myButtonListener.java file, you can simply do:
final Button btnOpenPopup = (Button)findViewById(R.id.menuButton);
btnOpenPopup.setOnClickListener(new myButtonListener);
The idea behind using
final Button btnOpenPopup = (Button)findViewById(R.id.menuButton);
btnOpenPopup.setOnClickListener(new
Button.OnClickListener()
{...}
such coding style is that the object and its implementation stays together at one place.
in above code we have used anonymous innerclass.
If you are not comfortable with such implementation then there is also another way of doing this.
In your activity, implement onClickListener like below:
public class MainActivity extends Activity implements OnClickListener{
Button btnOk;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//find id of your button
btnOk = (Button) findViewById(R.id.btnOk);
//Registering it for click listener
btnOk.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnOk:
System.out.println("OK button is clicked");
break;
case 2:
//some other controls
break;
default:
break;
}
}
}
Implement View.OnClickListener on your class and override its onClick method. That would make the code somewhat cleaner.
But first i recommend you to have proper knowledge of OOP and Java.
You just need to implement the OnClickListener interface and override the onCLick method. And on your onCLick() method you just need to add a filter for the corresponding View.
public void onClick(View arg0){
if(arg0 == myButton){
//do stuff when myButton is click
}else if(arg0 == myOtherButton){
//do stuff when myOtherButton is click
}
}
- What you have encountered is know as Anonymous Inner Class.
Anonymous Inner Class:
It has no name.
It must implements or extends one and only one Interface or Class respectively.
- This is just a way of coding where you keeping the functionality of that view or component attached visually.
The another way you can do that is by doing the following:
- Implement the specific Interface that has the call-back method.
public class MainActivity implements OnItemClickListener{
private Button buttonClick;
....
....
onCreate(Bundle saveInstance){
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
buttonClick = (Button)findViewById(R.id.button_click);
buttonClick.setOnClickListener(this);
...
...
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_click:
// -------- Do you function here
break;
}
}
}

Handle all click methods in one class?

Well lets say that I have an app that have like 50-60 buttons all around and I want to handle all click methods inside other package. How could I handle click for package app.test; class one in package app.test.clicks class clicks?
Create a class which implements OnClickListener,
public class ClickHandler implements OnClickListener
{
public void onClick(View v) {
//This method will be automatically implemented once OnClickListener is implemented.
}
}
Now set the onClickistener to your button like this,.
button.setOnClickListener(new ClickHandler());
And now inside the onClick() just do this,
public void onClick(View v) {
if(v.getId()==R.id.button)
{
//your stuff here.
}
}
If you need context object then,try v.getContext();. "v" is the parameter form the onClick().
make sure you import the package name of your ClickHandler class into your Activity.
But it would be much better if you had this as an inner class for each Activity.
public class HeaderActivity extends Activity implements OnClickListener{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button)findViewById(R.id.home)).setOnClickListener(this);
((Button)findViewById(R.id.search)).setOnClickListener(this);
((Button)findViewById(R.id.list)).setOnClickListener(this);
((Button)findViewById(R.id.filter)).setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.home:
Intent home=new Intent(this,HomeScreen.class);
startActivity(home);
finish();
break;
case R.id.search:
Intent search=new Intent(this,SearchScreen.class);
startActivity(search);
finish();
break;
case R.id.list:
Intent list=new Intent(this,ListScreen.class);
startActivity(list);
finish();
break;
case R.id.filter:
Intent filter=new Intent(this,FilterScreen.class);
startActivity(filter);
finish();
break;
default : break;
}
}
Well I don't think it will be a great idea to implement. However you need to pass the Context to clicks class. From context object you'll be able to get to the control which has been clicked and you can write your logic accordingly.

Categories

Resources