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