Meugiwara
Meugiwara

Reputation: 749

How to add button on each row in ListView?

I'm trying to implement button on each row in ListView, but I saw many topics and I don't succeeded to add code to mine. Here is my MainActivity :

public class MainActivity extends AppCompatActivity {

private ArrayAdapter<String> itemsAdapter;
private ArrayList<String> items;
private ImageButton formButton;
private ListView lvMain;

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

public void commonFunction() {
    lvMain = (ListView) findViewById(R.id.lvMain);
    items = new ArrayList<String>();
    readItems();
    itemsAdapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1,
            items);
    lvMain.setAdapter(itemsAdapter);
    formButton = (ImageButton) findViewById(R.id.btnPlus);
    formButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setLayoutActivity();
        }
    });
}
}

Here is my activity_main.xml :

<ListView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/lvMain"
    android:layout_above="@+id/btnPlus" />

<ImageButton
    android:layout_width="match_parent"
    android:layout_height="65dp"
    android:id="@+id/btnPlus"
    android:layout_alignParentBottom="true"
    app:srcCompat="@mipmap/ic_plus_foreground" />

Does someone any idea how to do ?

Upvotes: 0

Views: 568

Answers (3)

Birju Vachhani
Birju Vachhani

Reputation: 6353

Crate custom adapter and bind it with the ListView. Inflate custom layout for each row in the adapter. You can put your button in the custom layout file.

public class CustomAdapter extends ArrayAdapter<String> {

private Context context;

private int singleRowLayoutId;

public CustomAdapter(Context context, int singleRowLayoutId, String []titles, String []desc, int []images ) {
    super(context, singleRowLayoutId,titles);
    this.context=context;
    this.singleRowLayoutId=singleRowLayoutId; //custom row layout for list view item
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

    View row=convertView;
    CustomViewHolder holder=null;
    if(row==null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //view object of single row of list view
        row = inflater.inflate(singleRowLayoutId, parent, false);
        //by using holder, we make sure that findViewById() is not called every time.
        holder=new CustomViewHolder(row);
        row.setTag(holder);
    }
    else
    {
        holder=(CustomViewHolder)row.getTag();
    }

    return row;
}

private class CustomViewHolder {
    private ImageButton mbtn;

    CustomViewHolder(View view)
    {
        mbtn=(ImageButton)view.findViewById(R.id.btn);

        mbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //handle button click here
        }
    });
    }
}

Upvotes: 1

Sagar Kacha
Sagar Kacha

Reputation: 8464

Create custom adapter with custom row layout file and add button on that row file and bind it to List/Recycler view. So it will inflate in all row.

Add below code in row_list.xml file.

<ImageButton
android:layout_width="match_parent"
android:layout_height="65dp"
android:id="@+id/btnPlus"
android:layout_alignParentBottom="true"
app:srcCompat="@mipmap/ic_plus_foreground" />

CustomAdapter.java

public class CustomAdapter extends BaseAdapter {

private ArrayList data;
private static LayoutInflater inflater = null;


/*************  CustomAdapter Constructor *****************/
public CustomAdapter(ArrayList d) {

    /********** Take passed values **********/
    data = d;

    /***********  Layout inflater to call external xml layout () ***********/
    inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

/******** What is the size of Passed Arraylist Size ************/
public int getCount() {

    if (data.size() <= 0)
        return 1;
    return data.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

/********* Create a holder Class to contain inflated xml file elements *********/
public static class ViewHolder {
    public ImageButton button;

}

/****** Depends upon data size called for each row , Create each ListView row *****/
public View getView(int position, View convertView, ViewGroup parent) {

    View vi = convertView;
    ViewHolder holder;

    if (convertView == null) {

        /****** Inflate tabitem.xml file for each row ( Defined below ) *******/
        vi = inflater.inflate(R.layout.row_list, null);

        /****** View Holder Object to contain tabitem.xml file elements ******/

        holder = new ViewHolder();
        holder.button = (ImageView) vi.findViewById(R.id.btnPlus);

        /************  Set holder with LayoutInflater ************/
        vi.setTag(holder);
    } else
        holder = (ViewHolder) vi.getTag();

    holder.button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Button click
        }
    });
    return vi;
}}

Hope it will solve problem.

Happy coding!!

Upvotes: 1

Gabriella Angelova
Gabriella Angelova

Reputation: 2985

I think that this is what you need - create a separate layout for the rows in the list view. Then create a custom adapter, where you are adding this layout as row layout and then set this adapter to your list view. Here are the details with examples:

Android custom Row Item for ListView

Upvotes: 0

Related Questions