Android : How to set onClick event for Button in List item of ListView

I want to add onClick event for buttons used in item of Listview. How can I give onClick event for buttons in List Item.

205357 次浏览

You can set the onClick event in your custom adapter's getView method..
check the link http://androidforbeginners.blogspot.it/2010/03/clicking-buttons-in-listview-row.html

I assume you have defined custom adapter for your ListView.

If this is the case then you can assign onClickListener for your button inside the custom adapter's getView() method.

In your custom adapter inside getView method :

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Do things Here
}
});

In Adapter Class

public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.vehicals_details_row, parent, false);
Button deleteImageView = (Button) row.findViewById(R.id.DeleteImageView);
deleteImageView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//...
}
});
}

But you can get an issue - listView row not clickable. Solution:

  • make ListView focusable android:focusable="true"
  • Button not focusable android:focusable="false"

Try This,

public View getView(final int position, View convertView,ViewGroup parent)
{
if(convertView == null)
{
LayoutInflater inflater = getLayoutInflater();
convertView  = (LinearLayout)inflater.inflate(R.layout.YOUR_LAYOUT, null);
}


Button Button1= (Button)  convertView  .findViewById(R.id.BUTTON1_ID);


Button1.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// Your code that you want to execute on this button click
}


});




return convertView ;
}

It may help you....

This has been discussed in many posts but still I could not figure out a solution with:

android:focusable="false"
android:focusableInTouchMode="false"
android:focusableInTouchMode="false"

Below solution will work with any of the ui components : Button, ImageButtons, ImageView, Textview. LinearLayout, RelativeLayout clicks inside a listview cell and also will respond to onItemClick:

Adapter class - getview():

    @Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.my_ref_row, parent, false);
}
final Organization currentOrg = organizationlist.get(position).getOrganization();


TextView name = (TextView) view.findViewById(R.id.name);
Button btn = (Button) view.findViewById(R.id.btn_check);
btn.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
context.doSelection(currentOrg);


}
});


if(currentOrg.isSelected()){
btn.setBackgroundResource(R.drawable.sub_search_tick);
}else{
btn.setBackgroundResource(R.drawable.sub_search_tick_box);
}


}

In this was you can get the button clicked object to the activity. (Specially when you want the button to act as a check box with selected and non-selected states):

    public void doSelection(Organization currentOrg) {
Log.e("Btn clicked ", currentOrg.getOrgName());
if (currentOrg.isSelected() == false) {
currentOrg.setSelected(true);
} else {
currentOrg.setSelected(false);
}
adapter.notifyDataSetChanged();


}

In getview method put listener outside checking the view..try to follow this..it worked in my case..How to Increase or decrease value of edittext in listview's each row?

Class for ArrayList & ArrayAdapter

class RequestClass {
private String Id;
private String BookingTime;
private String UserName;
private String Rating;


public RequestClass(String Id,String bookingTime,String userName,String rating){
this.Id=Id;
this.BookingTime=bookingTime;
this.UserName=userName;
this.Rating=rating;
}


public String getId(){return Id; }
public String getBookingTime(){return BookingTime; }
public String getUserName(){return UserName; }
public String getRating(){return Rating; }




}

Main Activity:

 ArrayList<RequestClass> _requestList;
_requestList=new ArrayList<>();
try {
JSONObject jsonobject = new JSONObject(result);
JSONArray JO = jsonobject.getJSONArray("Record");
JSONObject object;
for (int i = 0; i < JO.length(); i++) {
object = (JSONObject) JO.get(i);


_requestList.add(new RequestClass( object.optString("playerID"),object.optString("booking_time"),
object.optString("username"),object.optString("rate") ));
}//end of for loop


RequestCustomAdapter adapter = new RequestCustomAdapter(context, R.layout.requestlayout, _requestList);
listView.setAdapter(adapter);

Custom Adapter Class

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;


import java.util.ArrayList;


/**
* Created by wajid on 1/12/2018.
*/


class RequestCustomAdapter extends ArrayAdapter<RequestClass> {
Context mContext;
int mResource;
public RequestCustomAdapter(Context context, int resource,ArrayList<RequestClass> objects) {
super(context, resource, objects);
mContext=context;
mResource=resource;
}
public static class ViewHolder{
RelativeLayout _layout;
TextView _bookingTime;
TextView _ratingTextView;
TextView _userNameTextView;
Button acceptButton;
Button _rejectButton;
}


@NonNull
@Override
public View getView(final int position, View convertView, ViewGroup parent){
final ViewHolder holder;
if(convertView == null) {
LayoutInflater inflater=LayoutInflater.from(mContext);
convertView=inflater.inflate(mResource,parent,false);
holder=new ViewHolder();
holder._layout = convertView.findViewById(R.id.requestLayout);
holder._bookingTime = convertView.findViewById(R.id.bookingTime);
holder._userNameTextView = convertView.findViewById(R.id.userName);
holder._ratingTextView = convertView.findViewById(R.id.rating);
holder.acceptButton = convertView.findViewById(R.id.AcceptRequestButton);
holder._rejectButton = convertView.findViewById(R.id.RejectRequestButton);


holder._rejectButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext, holder._rejectButton.getText().toString(), Toast.LENGTH_SHORT).show();
}
});


holder.acceptButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext, holder.acceptButton.getText().toString(), Toast.LENGTH_SHORT).show();
}
});




convertView.setTag(holder);


}
else{
holder=(ViewHolder)convertView.getTag();


}
holder._bookingTime.setText(getItem(position).getBookingTime());
if(!getItem(position).getUserName().equals("")){


holder._userNameTextView.setText(getItem(position).getUserName());
}
if(!getItem(position).getRating().equals("")){
holder._ratingTextView.setText(getItem(position).getRating());
}
return  convertView;
}


}

ListView in Main xml:

<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:id="@+id/AllRequestListView">


</ListView>

Resource Layout for list view requestlayout.xml:

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/requestLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/bookingTime"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/bookingTime"
android:text="Temp Name"
android:id="@+id/userName"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/userName"
android:text="No Rating"
android:id="@+id/rating"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/AcceptRequestButton"
android:focusable="false"
android:layout_below="@+id/rating"
android:text="Accept"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/RejectRequestButton"
android:layout_below="@+id/AcceptRequestButton"
android:focusable="false"
android:text="Reject"
/>


</RelativeLayout>

I find

final Button yourButton = (Button)view.findViewById(R.id.your_button);
yourButton.setFocusable(false);
yourButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
...///);

can solve the problem. If you want to get some data when clicking the button, using tags is helpful. Here the button is declared final because it will be used within inner class.

FOR KOTLIN USERS

inside your getView(...) method if you try to start an activity through button onClickListener:

   myButton.setOnClickListener{
val intent = Intent(this@CurrentActivity, SecondActivity::class.java)
startActivity(intent)
}

Pass the correct pointer for "this"