Friday, December 26, 2014

Android Listview with Checkbox (Custom Adapter)

Hi Guys!

Today I'm going to share with you how to add Checkbox on your Listview  and getting all selected values in your list.

IDE - Android Studio 1.0
Reference: BaseAdapter

Process Flow of the App:

















Java codes that you needed:

1. Item.java
package com.example.user.listviewxcheckbox;

public class Item {

    String name;
    boolean checkbox;

    public Item() {
         /*Empty Constructor*/
    }
    public  Item(String country, boolean status){
        this.name = country;
        this.checkbox = status;
    }
    //Getter and Setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isCheckbox() {
        return checkbox;
    }

    public void setCheckbox(boolean checkbox) {
        this.checkbox = checkbox;
    }

}

2. ItemSelectedAdapter.java
package com.example.user.listviewxcheckbox;

import android.view.LayoutInflater;
import java.util.ArrayList;
import android.view.View;
import android.view.ViewGroup;
import android.content.Context;
import android.widget.BaseAdapter;
import android.widget.*;
/**
 * Created by Eugene Alvizo on 12/26/2014.
 */
public class ItemSelectedAdapter extends BaseAdapter{

    private Context activity;
    private ArrayList<item> data;
    private static LayoutInflater inflater = null;
    private View vi;
    private ViewHolder viewHolder;

    public ItemSelectedAdapter(Context context, ArrayList&lt;Item&gt;<item> items) {
        this.activity = context;
        this.data = items;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int i) {
        return i;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {
        vi = view;
      //Populate the Listview
        final int pos = position;
        Item items = data.get(pos);
        if(view == null) {
            vi = inflater.inflate(R.layout.listview_item, null);
            viewHolder = new ViewHolder();
            viewHolder.checkBox = (CheckBox) vi.findViewById(R.id.checkbox);
            viewHolder.name = (TextView) vi.findViewById(R.id.name);
            vi.setTag(viewHolder);
        }else
            viewHolder = (ViewHolder) view.getTag();
        viewHolder.name.setText(items.getName());
        if(items.isCheckbox()){
            viewHolder.checkBox.setChecked(true);
        }
        else {
            viewHolder.checkBox.setChecked(false);
        }
        return vi;
    }
    public ArrayList<item> getAllData(){
        return data;
    }
    public void setCheckBox(int position){
       //Update status of checkbox
        Item items = data.get(position);
        items.setCheckbox(!items.isCheckbox());
        notifyDataSetChanged();
    }

    public class ViewHolder{
        TextView name;
        CheckBox checkBox;
    }
}


3. MainActivity.java

package com.example.user.listviewxcheckbox;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;


public class MainActivity extends ActionBarActivity {
    private  Item itemHandler;
    private ItemSelectedAdapter adapter;
    private ArrayList<item> itemList;
    private ListView listView;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView =(ListView) findViewById(R.id.listview);
        button = (Button) findViewById(R.id.printbtn);
        setWidget();
    }
    public void setWidget(){
       //Adding data to ArrayList
        itemList = new ArrayList&lt;Item&gt;<item>();
        itemList.add(new Item("Philippines", false));
        itemList.add(new Item("America", false));
        itemList.add(new Item("Thailand", false));
        itemList.add(new Item("Korea", false));
        itemList.add(new Item("Japan", false));
        itemList.add(new Item("China", false));
        itemList.add(new Item("Australia", false));
        itemList.add(new Item("Canada", false));
        itemList.add(new Item("Italy", false));
        itemList.add(new Item("Iraq", false));
        //Setup Adapter for Listview
        adapter = new ItemSelectedAdapter(MainActivity.this,itemList);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView adapterView, View view, int position, long l) {
               //Item Selected from list
                adapter.setCheckBox(position);

            }
        });

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               //Display All Item Selected
                String countries = "";
                for(Item hold: adapter.getAllData()){
                    if(hold.isCheckbox()){
                        countries += " "  + hold.getName();
                    }
                }
                Toast.makeText(MainActivity.this,"Names: " + countries,Toast.LENGTH_SHORT).show();
            }
        });

    }
}
XML(Layouts) codes that you needed:

1.activity_main.xml
<LinearLayout 
      android:layout_height="match_parent" 
      android:layout_width="match_parent" 
      android:orientation="vertical" 
      tools:context=".MainActivity" 
      xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:tools="http://schemas.android.com/tools">

    <ListView 
      android:id="@+id/listview" 
      android:layout_height="514dp" 
      android:layout_width="fill_parent"/>
    <Button 
      android:id="@+id/printbtn"
      android:layout_height="fill_parent" 
      android:layout_width="fill_parent" 
      android:text="Print"/>
   
 </LinearLayout>
2.listview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:descendantFocusability="blocksDescendants">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal"
        android:gravity="center">
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:gravity="center_vertical"
            android:paddingLeft="30dp"
            android:layout_weight=".8">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Item"
                android:id="@+id/name"
                android:focusable="false"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight=".1">
            <CheckBox
                android:layout_width="45dp"
                android:layout_height="45dp"
                android:checked="true"
                android:focusable="false"
                android:clickable="false"
                android:id="@+id/checkbox" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

OUTPUT:






Download Source Code


16 comments:

  1. I am getting an error on for(Item hold: adapter.getAllData()){ Incompatible type reuqired object returned Item

    ReplyDelete
    Replies
    1. Make sure you have this code on your BaseAdapter

      public ArrayList getAllData(){
      return data;
      }

      Delete
  2. Thank you so much .its work like charm and very useful to me.

    ReplyDelete
  3. Hi, Eugene, Your post looks good. helped me to implement the list with checkbox. But i am facing issue with search filter on list view. When i search the list item and check the box than it gets unchecked after i clear search field. kindly help.

    ReplyDelete
    Replies
    1. Thanks Akki, Don't reset the data inside your Model, Just notify them using notifyChangeAdapter and the Adapter will work on it for the binding the right value of each views in the listItem.

      Delete
  4. Hi I have an error.
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.CheckBox.setChecked(boolean)' on a null object reference

    it shows viewHolder.checkBox.setChecked(false); line
    Help pls, I googled it but couldn't find a solution

    ReplyDelete
  5. The logs says that viewHolder class can't find the Checkbox. Please check your listview_item.xml if checkbox is already declared there so it will not invoke null object in your viewHolder.

    ReplyDelete
  6. Thank you so much, its save my time...

    ReplyDelete
  7. Thank you so much, its save my time...

    ReplyDelete
  8. Please see to this issue
    https://stackoverflow.com/questions/44561788/checkbox-checked-unchecked-state-changes-on-scroll-listview-baseadapter

    ReplyDelete
    Replies
    1. its calling if condition above the checkbox vi.setOnClickListener again again and making my checkbox to go its previous sate again

      Delete
  9. Thanks, 2 weeks I was searching for something like that.
    And it works!

    ReplyDelete