Android ListView with Checkbox example

In this example, I present:

  • How to combine check box to "filter" ListView elements.
  • Sending a Parcelable object or a list of Parcelable objects through Intent.
  • Adding many view elements to a ViewGroup

Now, Let's start an Android project!

Defining a Friend object for use. Implement Parcelable to put through Intent later. Friend.java source code may be like this:
Friend.java
public class Friend implements Parcelable {

    private boolean gender;
    private String name;
    private boolean isSelected;

    /**
     * Create parcelable of friend
     */
    public static final Parcelable.Creator<Friend> CREATOR = new Parcelable.Creator<Friend>() {
 public Friend createFromParcel(Parcel in) {
     return new Friend(in);
 }

 public Friend[] newArray(int size) {
     return new Friend[size];
 }
    };

    /**
     * Create Friend from Parcel object.
     * 
     * @param in
     */
    public Friend(Parcel in) {
 this.name = in.readString();
 this.gender = in.readByte() != 0;
 this.isSelected = in.readByte() != 0;
    }

    @Override
    public int describeContents() {
 return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
 dest.writeString(this.name);
 dest.writeByte((byte) (this.gender ? 1 : 0));
 dest.writeByte((byte) (this.isSelected ? 1 : 0));
    }

    public Friend(String name, boolean gender) {
 this.name = name;
 this.gender = gender; // true is male, false is woman
 this.isSelected = false; // not selected when create
    }

    public boolean isGender() {
 return gender;
    }

    public void setGender(boolean gender) {
 this.gender = gender;
    }

    public String getName() {
 return name;
    }

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

    public boolean isSelected() {
 return isSelected;
    }

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

}
Next, we will create MainActivity. In this, we have some important methods:

  •  setListViewHeader(): add header for ListView, click at this header button, we will go to SelectedListActivity contain all friends which checked.
  •  setAdapterData): provide data for ListView.
  • Handling event for "Go to selected list" button.

Source code:
MainActivity.java
public class MainActivity extends Activity {

    private ListView listView;
    private View btnList;

    private ArrayList<Friend> friends;
    private ListViewAdapter adapter;

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

 listView = (ListView) findViewById(R.id.list_view);
 setListViewHeader();
 setListViewAdapter();
 setAdapterData();
 btnList.setOnClickListener(gotoSelectedListActivity()); // go to checked list
        
    }

    /**
     * set listview footer method
     */
    private void setListViewHeader() {
 LayoutInflater inflater = getLayoutInflater();
 ViewGroup header = (ViewGroup) inflater.inflate(
  R.layout.header_listview, listView, false);
 listView.addHeaderView(header, null, false);

 btnList = (Button) findViewById(R.id.button);
    }

    private void setListViewAdapter() {
 friends = new ArrayList<Friend>();
 adapter = new ListViewAdapter(this, R.layout.item_listview, friends);
 listView.setAdapter(adapter);
    }

    private void setAdapterData() {
 friends.add(new Friend("Harry Brown", true));
 friends.add(new Friend("Nguyen Tuan Anh", true));
 friends.add(new Friend("Rin Zuzuki", false));
 friends.add(new Friend("Zheng Lee", true));
 friends.add(new Friend("Ana Olenhina", false));
 friends.add(new Friend("Nhat Trang", false));
 friends.add(new Friend("Mai Phuong", false));
 friends.add(new Friend("Yasmin Abdulaziz", false));
 friends.add(new Friend("Park Ji Won", true));

 adapter.notifyDataSetChanged(); // update adapter
    }

    /**
     * handle footer listview button event
     * @return
     */
    private OnClickListener gotoSelectedListActivity() {
 return new OnClickListener() {
     
     @Override
     public void onClick(View v) {
  Intent intent = new Intent(MainActivity.this, SelectedListActivity.class);
  intent.putParcelableArrayListExtra("Checked List", friends);
  startActivity(intent);
     }
 };
    }
}
And this is activity_main.xml file for layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.blogspot.hongthaiit.listviewwithcheckbox.MainActivity" >

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none" >
    </ListView>

</RelativeLayout>
As already mentioned above, we must create SelectedListActivity to show selected elements. In this activity, I will present the way to add many elements to a LinearLayout in generateDataToContainerLayout() method. Full file source code:
SelectedListActivity.java
public class SelectedListActivity extends Activity {

    private LinearLayout container;
    private ArrayList<Friend> checkedList;

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

 container = (LinearLayout) findViewById(R.id.layout);
 checkedList = new ArrayList<Friend>(); // initializing list
 getDataFromIntent(); // receive data from intent (put by MainActivity)
 generateDataToContainerLayout();
    }

    private void getDataFromIntent() {
 checkedList = getIntent().getParcelableArrayListExtra("Checked List");
 Log.i("ListActivity", "size" + checkedList.size());
    }

    @SuppressLint("InflateParams") 
    private void generateDataToContainerLayout() {

 int i = 0;
 if (checkedList.size() == i) { //do nothing
 }
 while (checkedList.size() > i) {
     final Friend friend = checkedList.get(i);
     LayoutInflater inflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
     View view = inflater.inflate(R.layout.item_listview, null,
      false);

     ImageView genderImage = (ImageView) view.findViewById(R.id.gender);
     TextView friendName = (TextView) view.findViewById(R.id.name);
     CheckBox checked = (CheckBox)view.findViewById(R.id.check);
     checked.setVisibility(View.GONE);
     if (friend.isSelected()) {
  Log.i("ListActivity", "here" + friend.getName());
  friendName.setText(friend.getName());
  if (friend.isGender()) {
      genderImage.setImageResource(R.drawable.male);
  } else {
      genderImage.setImageResource(R.drawable.female);
  }

  // add view after all
  container.addView(view);
     }

     i++; // rise i
 }
    }
}
Other work is creating a ListView adapter. We should extend ArrayAdapter, not BaseAdapter, it's more convenient:
ListViewAdapter.java
public class ListViewAdapter extends ArrayAdapter<Friend> {

    private Activity activity;
    private ArrayList<Friend> Friends;
    private final String TAG = ListViewAdapter.class.getSimpleName();

    public ListViewAdapter(Activity activity, int resource, ArrayList<Friend> Friends) {
 super(activity, resource, Friends);
 this.activity = activity;
 this.Friends = Friends;
 Log.i(TAG, "init adapter");
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
 ViewHolder holder = null;

 // inflate layout from xml
 LayoutInflater inflater = (LayoutInflater) activity
  .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
 
 // If holder not exist then locate all view from UI file.
 if (convertView == null) {
     // inflate UI from XML file
     convertView = inflater.inflate(R.layout.item_listview, parent, false);
     // get all UI view
     holder = new ViewHolder(convertView);
     // set tag for holder
     convertView.setTag(holder);
 } else {
     // if holder created, get tag from view
     holder = (ViewHolder) convertView.getTag();
 }
 
 Friend friend = Friends.get(position);
 
 //set Friend data to views
 holder.name.setText(friend.getName());
 if (friend.isGender()) {
     holder.image.setImageDrawable(this.activity.getResources()
      .getDrawable(R.drawable.male));
 } else {
     holder.image.setImageDrawable(this.activity.getResources()
      .getDrawable(R.drawable.female));
 }
 
 //set event for checkbox
 holder.check.setOnCheckedChangeListener(onCheckedChangeListener(friend));

 return convertView;
    }

    /**
     * handle check box event
     * @param f
     * @return
     */
    private OnCheckedChangeListener onCheckedChangeListener(final Friend f) {
 return new OnCheckedChangeListener() {
     
     @Override
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  if (isChecked) {
      f.setSelected(true);
  } else {
      f.setSelected(false);
  }
     }
 };
    }

    private class ViewHolder {
 private ImageView image;
 private TextView name;
 private CheckBox check;

 public ViewHolder(View v) {
     image = (ImageView) v.findViewById(R.id.gender);
     name = (TextView) v.findViewById(R.id.name);
     check = (CheckBox) v.findViewById(R.id.check);
 }
    }

}
And these are some xml files we need:
- activity_list.xml (Layout for SelectedActivity.java):
<?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="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#666666"
        android:layout_marginTop="10dp"
        android:textColor="@android:color/white"
        android:text="@string/ckecked" />

    <LinearLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    </LinearLayout>

</LinearLayout>
- item_listview.xml (Layout for each ListView row):
<?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="match_parent"
    android:orientation="horizontal" >

    <CheckBox
        android:id="@+id/check"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.1" />

    <ImageView
        android:id="@+id/gender"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.35"
        android:contentDescription="@string/action_settings" />

    <TextView
        android:id="@+id/name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.45"
        android:textColor="@android:color/holo_green_dark" />

</LinearLayout>
- header_listview.xml (to make the ListView header):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#555555" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="@string/friend"
        android:textColor="@android:color/white" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerInParent="true"
        android:layout_marginLeft="5dp"
        android:layout_toRightOf="@+id/text"
        android:background="@drawable/blue_button"
        android:contentDescription="@string/action_settings"
        android:text="@string/goto_selected_list"
        android:textColor="@android:color/white"
        android:textSize="14sp" />

</RelativeLayout>

Running program, we have result like these srceens (click each image for full screen):
pic name pic name pic name


Share


Previous post
« Prev Post
Next post
Next Post »