Android: How to Handle Button Click

Android: how to handle button click

Question 1:
Unfortunately the one in which you you say is most intuitive is the least used in Android. As I understand, you should separate your UI (XML) and computational functionality (Java Class Files). It also makes for easier debugging. It is actually a lot easier to read this way and think about Android imo.

Question 2:
I believe the two mainly used are #2 and #3. I will use a Button clickButton as an example.

2

is in the form of an anonymous class.

Button clickButton = (Button) findViewById(R.id.clickButton);
clickButton.setOnClickListener( new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
***Do what you want with the click here***
}
});

This is my favorite as it has the onClick method right next to where the button variable was set with the findViewById. It seems very neat and tidy that everything that deals with this clickButton Button View is located here.

A con that my coworker comments, is that imagine you have many views that need onclick listener. You can see that your onCreate will get very long in length. So that why he likes to use:

3

Say you have, 5 clickButtons:

Make sure your Activity/Fragment implement OnClickListener

// in OnCreate

Button mClickButton1 = (Button)findViewById(R.id.clickButton1);
mClickButton1.setOnClickListener(this);
Button mClickButton2 = (Button)findViewById(R.id.clickButton2);
mClickButton2.setOnClickListener(this);
Button mClickButton3 = (Button)findViewById(R.id.clickButton3);
mClickButton3.setOnClickListener(this);
Button mClickButton4 = (Button)findViewById(R.id.clickButton4);
mClickButton4.setOnClickListener(this);
Button mClickButton5 = (Button)findViewById(R.id.clickButton5);
mClickButton5.setOnClickListener(this);

// somewhere else in your code

public void onClick(View v) {
switch (v.getId()) {
case R.id.clickButton1: {
// do something for button 1 click
break;
}

case R.id.clickButton2: {
// do something for button 2 click
break;
}

//.... etc
}
}

This way as my coworker explains is neater in his eyes, as all the onClick computation is handled in one place and not crowding the onCreate method. But the downside I see is, that the:

  1. views themselves,
  2. and any other object that might be located in onCreate used by the onClick method will have to be made into a field.

Let me know if you would like more information. I didn't answer your question fully because it is a pretty long question. And if I find some sites I will expand my answer, right now I'm just giving some experience.

how to add button click event in android studio

SetOnClickListener (Android.View.view.OnClickListener) in View cannot
be applied to (com.helloandroidstudio.MainActivity)

This means in other words (due to your current scenario) that your MainActivity need to implement OnClickListener:

public class Main extends ActionBarActivity implements View.OnClickListener {
// do your stuff
}

This:

buttonname.setOnClickListener(this);

means that you want to assign listener for your Button "on this instance" -> this instance represents OnClickListener and for this reason your class have to implement that interface.

It's similar with anonymous listener class (that you can also use):

buttonname.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View view) {

}
});

Button on click listener

You have three options:

common in 1,2) You need to assign an id to each of your buttons in the layout XML file

<Button android:id="@+id/my_button1"
..........
/>
<Button android:id="@+id/my_button2"
..........
/>

1) In the activity's onCreate() method after setContentView() you need to set a new OnClickListener for each button.

 public class MyActivity extends Activity  {
int a;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button myButton1 = (Button) findViewById(R.id.my_button1);
Button myButton2 = (Button) findViewById(R.id.my_button2);

myButton1.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
// Do what you want here
a = 1;
}
});

myButton2.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
// Do what you want here
a = 2;
}
});
}

2) As you see in the first approach, we need to make a new Object from the OnClickListener for each button. We can mix all that into one OnClickListener for performance and readability reasons.

public class MyActivity extends Activity implements View.OnClickListener {
int a;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button myButton1 = (Button) findViewById(R.id.my_button1);
myButton1.setOnClickListener(this);
Button myButton2 = (Button) findViewById(R.id.my_button2);
myButton2.setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.my_button_1:
a = 1;
break;
case R.id.my_button_2:
a = 2;
break;
}
}
...
}

3) You don't need to assign an id for this option you just need to assign the method name in the XML and then implement the same method in the activity with the exact same name but it must take a View object as an argument.

<Button 
...
android:onClick="button1Click" />

<Button
...
android:onClick="button2Click" />

and then in your activity just write the methods.

public class MyActivity extends Activity implements View.OnClickListener {
int a;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void button1Click(View v) {
a = 1;
}

public void button2Click(View v) {
a = 2;
}
}

That's all your options. I personally prefer number 2.

Handling button click and button touch simultaneously in Kotlin

Because onTouch and onClick will conflict,When you consume the event in onTouchListener, that is return@setOnTouchListener true; will not execute the click again, if you want the click event to be executed after ACTION_UP, just return@setOnTouchListener false

Like Selvin said, if you just want to change the color or background of the button when pressed, you shouldn't do it this way,use drawable selector is the best!

Handle Button click inside a row in RecyclerView

this is how I handle multiple onClick events inside a recyclerView:

Edit : Updated to include callbacks (as mentioned in other comments). I have used a WeakReference in the ViewHolder to eliminate a potential memory leak.

Define interface :

public interface ClickListener {

void onPositionClicked(int position);

void onLongClicked(int position);
}

Then the Adapter :

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

private final ClickListener listener;
private final List<MyItems> itemsList;

public MyAdapter(List<MyItems> itemsList, ClickListener listener) {
this.listener = listener;
this.itemsList = itemsList;
}

@Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_row_layout), parent, false), listener);
}

@Override public void onBindViewHolder(MyViewHolder holder, int position) {
// bind layout and data etc..
}

@Override public int getItemCount() {
return itemsList.size();
}

public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {

private ImageView iconImageView;
private TextView iconTextView;
private WeakReference<ClickListener> listenerRef;

public MyViewHolder(final View itemView, ClickListener listener) {
super(itemView);

listenerRef = new WeakReference<>(listener);
iconImageView = (ImageView) itemView.findViewById(R.id.myRecyclerImageView);
iconTextView = (TextView) itemView.findViewById(R.id.myRecyclerTextView);

itemView.setOnClickListener(this);
iconTextView.setOnClickListener(this);
iconImageView.setOnLongClickListener(this);
}

// onClick Listener for view
@Override
public void onClick(View v) {

if (v.getId() == iconTextView.getId()) {
Toast.makeText(v.getContext(), "ITEM PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(v.getContext(), "ROW PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
}

listenerRef.get().onPositionClicked(getAdapterPosition());
}

//onLongClickListener for view
@Override
public boolean onLongClick(View v) {

final AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setTitle("Hello Dialog")
.setMessage("LONG CLICK DIALOG WINDOW FOR ICON " + String.valueOf(getAdapterPosition()))
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

}
});

builder.create().show();
listenerRef.get().onLongClicked(getAdapterPosition());
return true;
}
}
}

Then in your activity/fragment - whatever you can implement : Clicklistener - or anonymous class if you wish like so :

MyAdapter adapter = new MyAdapter(myItems, new ClickListener() {
@Override public void onPositionClicked(int position) {
// callback performed on click
}

@Override public void onLongClicked(int position) {
// callback performed on click
}
});

To get which item was clicked you match the view id i.e. v.getId() == whateverItem.getId()

Hope this approach helps!



Related Topics



Leave a reply



Submit