Android ListView Checkbox Example - OnItemClickListener() and OnClickListener()

In this example we are going to place a Checkbox inside the ListView row along with some Text. The concept is the same if you want to place a button or an image or all of them. The first issue that I faced when placing a Checkbox is the OnItemClickListener stopped working. To get around that you have to specify android:focusable="false" and android:focusableInTouchMode="false" for your checkbox view. Now to listen for the click event on the checkbox you have attach the OnClickListener when the you are inflating the custom layout inside your getView() method. To find out what all checkboxes are selected just loop thru the ArrayList that is being maintained by listening to the onClick event for the checkbox.

Android ListView Checkbox Example
Android ListView Checkbox Example
Android ListView Checkbox Example

Source for Activity - ListViewCheckboxesActivity.java

package com.as400samplecode;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class ListViewCheckboxesActivity extends Activity {

 MyCustomAdapter dataAdapter = null;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  //Generate list View from ArrayList
  displayListView();

  checkButtonClick();

 }

 private void displayListView() {

  //Array list of countries
  ArrayList<Country> countryList = new ArrayList<Country>();
  Country country = new Country("AFG","Afghanistan",false);
  countryList.add(country);
  country = new Country("ALB","Albania",true);
  countryList.add(country);
  country = new Country("DZA","Algeria",false);
  countryList.add(country);
  country = new Country("ASM","American Samoa",true);
  countryList.add(country);
  country = new Country("AND","Andorra",true);
  countryList.add(country);
  country = new Country("AGO","Angola",false);
  countryList.add(country);
  country = new Country("AIA","Anguilla",false);
  countryList.add(country);

  //create an ArrayAdaptar from the String Array
  dataAdapter = new MyCustomAdapter(this,
    R.layout.country_info, countryList);
  ListView listView = (ListView) findViewById(R.id.listView1);
  // Assign adapter to ListView
  listView.setAdapter(dataAdapter);


  listView.setOnItemClickListener(new OnItemClickListener() {
   public void onItemClick(AdapterView<?> parent, View view,
     int position, long id) {
    // When clicked, show a toast with the TextView text
    Country country = (Country) parent.getItemAtPosition(position);
    Toast.makeText(getApplicationContext(),
      "Clicked on Row: " + country.getName(), 
      Toast.LENGTH_LONG).show();
   }
  });

 }

 private class MyCustomAdapter extends ArrayAdapter<Country> {

  private ArrayList<Country> countryList;

  public MyCustomAdapter(Context context, int textViewResourceId, 
    ArrayList<Country> countryList) {
   super(context, textViewResourceId, countryList);
   this.countryList = new ArrayList<Country>();
   this.countryList.addAll(countryList);
  }

  private class ViewHolder {
   TextView code;
   CheckBox name;
  }

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

   ViewHolder holder = null;
   Log.v("ConvertView", String.valueOf(position));

   if (convertView == null) {
   LayoutInflater vi = (LayoutInflater)getSystemService(
     Context.LAYOUT_INFLATER_SERVICE);
   convertView = vi.inflate(R.layout.country_info, null);

   holder = new ViewHolder();
   holder.code = (TextView) convertView.findViewById(R.id.code);
   holder.name = (CheckBox) convertView.findViewById(R.id.checkBox1);
   convertView.setTag(holder);

    holder.name.setOnClickListener( new View.OnClickListener() {  
     public void onClick(View v) {  
      CheckBox cb = (CheckBox) v ;  
      Country country = (Country) cb.getTag();  
      Toast.makeText(getApplicationContext(),
       "Clicked on Checkbox: " + cb.getText() +
       " is " + cb.isChecked(), 
       Toast.LENGTH_LONG).show();
      country.setSelected(cb.isChecked());
     }  
    });  
   } 
   else {
    holder = (ViewHolder) convertView.getTag();
   }

   Country country = countryList.get(position);
   holder.code.setText(" (" +  country.getCode() + ")");
   holder.name.setText(country.getName());
   holder.name.setChecked(country.isSelected());
   holder.name.setTag(country);

   return convertView;

  }

 }

 private void checkButtonClick() {


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

   @Override
   public void onClick(View v) {

    StringBuffer responseText = new StringBuffer();
    responseText.append("The following were selected...\n");

    ArrayList<Country> countryList = dataAdapter.countryList;
    for(int i=0;i<countryList.size();i++){
     Country country = countryList.get(i);
     if(country.isSelected()){
      responseText.append("\n" + country.getName());
     }
    }

    Toast.makeText(getApplicationContext(),
      responseText, Toast.LENGTH_LONG).show();

   }
  });

 }

}

Source for POJO - Country.java

package com.as400samplecode;

public class Country {
 
 String code = null;
 String name = null;
 boolean selected = false;
 
 public Country(String code, String name, boolean selected) {
  super();
  this.code = code;
  this.name = name;
  this.selected = selected;
 }
 
 public String getCode() {
  return code;
 }
 public void setCode(String code) {
  this.code = code;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }

 public boolean isSelected() {
  return selected;
 }
 public void setSelected(boolean selected) {
  this.selected = selected;
 }
 
}

Source for Main Screen Layout - main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView android:layout_width="fill_parent"
  android:layout_height="wrap_content" android:padding="10dp"
  android:text="@string/some_text" android:textSize="20sp" />


    <Button
        android:id="@+id/findSelected"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Find countries that are Selected" />

 <ListView android:id="@+id/listView1" android:layout_width="fill_parent"
  android:layout_height="fill_parent" />

</LinearLayout>

Source for Custom List Layout - country_info.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="6dip" >

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="CheckBox" />

    <TextView
        android:id="@+id/code"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/checkBox1"
        android:layout_alignBottom="@+id/checkBox1"
        android:layout_toRightOf="@+id/checkBox1"
        android:text="TextView" />

</RelativeLayout>


Source for application variables - strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">ListView Checkboxes</string>
 <string name="some_text">
     Some North American Countries!
 </string>
    
</resources>

Source for application manifest - AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.as400samplecode"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" 
        android:theme="@android:style/Theme.Holo.Light">
        <activity
            android:name=".ListViewCheckboxesActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

References


37 comments :

  1. Thanks. it helps me a lot

    ReplyDelete
  2. I hope this is the only code in internet which explains the concepts clearly.
    Thank you very much !

    ReplyDelete
  3. Hello,
    If sb has a problem with error: "The application has stopped..." he should try to delete the line: holder.code.setText(" (" + country.getCode() + ")");
    And by the way, thanks for tutorial.

    ReplyDelete
  4. Thank you very much, it helped me a lot. Wonderful tutorial!

    ReplyDelete
  5. Hi, can we display the entire content using inflator and toast i.e Afghanistan(AFG)or anything we add after the country's name when we click on the check box, because in the output only the country's name is displayed not the (AFG) which has also been added in it. If yes, then provide me the coding or concept how to display.
    Please reply asap.
    Thanks.

    ReplyDelete
    Replies
    1. You can just do country.getCode() and display that as the checkbox has country object in the setTag method.

      Delete
  6. Thanks for your instant reply, but this setTag method is also not helping to retrieve the country code,thus can you provide me with some other concept or with the coding part which will help me to get the codes too along with the country's name in the output when I click.
    Waiting for your response.
    Thanks in advance.

    ReplyDelete
  7. Great work. It solved my long time issue

    ReplyDelete
  8. Thank you for this great solution.

    ReplyDelete
  9. Thank you :) Nice Tutorial... Keep posting...Keep Helping !
    God Bless You :)

    ReplyDelete
  10. if we want to add checkall button then how can we implement

    ReplyDelete
    Replies
    1. I think all you need to do is update the arrayList objects to true for the checkbox value and then call the ArrayAdapter notifyDataSetChanged() method which basically notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.

      Delete
    2. Can you show us how to change the codes.

      Delete
  11. Great tutorial, but why when I have more than 10 elements and select one element some other elements are also selected (let's say that the 11th e.g.)?

    ReplyDelete
  12. if we want delete checked item from arraylist how can we do it??
    Specially Loop part

    ReplyDelete
  13. how to remove selected item in listview ???

    ReplyDelete
  14. Can i have the full source code file for learning purpose?
    because i get a lot of error when apply the code(by copy and paste file from this site to my eclipse) .thx

    ReplyDelete
  15. i mean after i paste the code from this site, i got alot of error. :)

    ReplyDelete
  16. please give source code

    ReplyDelete
  17. Thank you soooooo much...this code has helped me alot..Gr8 work..!!!

    ReplyDelete
  18. thanks soooo much
    please, could you send to me the source code ?

    sara.alhrbi@gmail.com

    ReplyDelete
  19. Great article. Had been searching for something like this on listview for a while. Would love to see more like this.

    ReplyDelete
  20. Thank you for the work.
    I have tried to copy and paste the above code in Eclipse but I get a lot of errors.
    Was someone able to do it works? What are the problems?
    Thank you

    ReplyDelete
  21. Hi i want to list contacts with checkbox and after that want to handle selected items .. can you help me thank you..

    ReplyDelete
  22. Thankx Dear... Your Code Is helping and Related ....
    Ever Your Code is very simple and understandable . :)

    ReplyDelete
  23. Thanx a lot!!!
    I looked for hours to find a tutorial like this.

    ReplyDelete
  24. thanks...........................

    ReplyDelete
  25. Thanks for two
    android:focusable="false"
    android:focusableInTouchMode="false"

    ReplyDelete
  26. can you please give the full source code? I am a newbie here, i copied your code but i got many errors..

    ReplyDelete
  27. can please show some example on how to the string in shared preferences..im newbie here..thank you..

    ReplyDelete
  28. Hey It helped me a lot!
    But how could I use a filter in my listView?

    I have an EditText field and I want to enter text into the same, realiazar one looks in my listView!

    How would I proceed?

    I am Brazilian, sorry for my mistakes in English!

    ReplyDelete
  29. what if i do checkbox.performclick() in onlistitem click method ??

    ReplyDelete
  30. The best explanation on the Internet by far, well done, thank you.

    ReplyDelete
  31. Very nice one.. Thank u so much..

    ReplyDelete
  32. Muito bem. Me ajudo pra caramba. com este tutorial

    ReplyDelete