title: Expandable listview like tree view in android
body: <p>I want to create a tree view in android. I tried to implement an expandable listview with checkboxes. I want that when list group checkbox is checked, then all the list items under group will be selected. The user might be able to select particular items in the listview.</p>
  
  <p>Please look at the images:</p>
  
  <p><img src="https://i.stack.imgur.com/IxX7w.png" alt="All items collapsed, 2013-2014 is selected!"> </p>
  
  <p><img src="https://i.stack.imgur.com/ZY7ve.png" alt="Particular months selected"></p>
  
  <p><img src="https://i.stack.imgur.com/XWCm1.png" alt="2011-2012 selected"></p>
  
  <p>How should I do this in android? The issue which I am facing is that, if I add a checkbox to group of the expandable listview, the list can not be expanded any more.</p>
  
  <p><strong>Source code</strong>:</p>
  
  <p><strong>activity_main.xml</strong>:</p>
  
  <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical"
      android:background="#f4f4f4" &gt;
  
              &lt;ExpandableListView
                  android:id="@+id/lvExp"
                  android:layout_height="match_parent"
                  android:layout_width="match_parent"
                  android:cacheColorHint="#00000000"/&gt;   
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p><strong>list_group.xml</strong>:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical"
      android:padding="8dp"
      android:background="#CC7A00"&gt;
  
      &lt;CheckBox
          android:id="@+id/lblListHeaderCheckbox"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:text="" 
          android:textSize="17dp"
          android:textColor="#ffffff"/&gt;
  
      &lt;TextView
          android:id="@+id/lblListHeader"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
          android:textSize="17dp"
          android:textColor="#ffffff" /&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p><strong>list_item.xml</strong>:</p>
  
  <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="55dip"
      android:orientation="vertical" 
      android:background="#FFCC80"&gt;
  
      &lt;TextView
          android:id="@+id/lblListItem"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:textSize="17dip"
          android:paddingTop="5dp"
          android:paddingBottom="5dp"
          android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" 
          android:textColor="#336699"/&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p><strong>MainActivity</strong>:</p>
  
  <pre><code>public class MainActivity extends Activity {
  
      ExpandableListAdapter listAdapter;
      ExpandableListView expListView;
      List&lt;String&gt; listDataHeader;
      HashMap&lt;String, List&lt;String&gt;&gt; listDataChild;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          // get the listview
          expListView = (ExpandableListView) findViewById(R.id.lvExp);
  
          // preparing list data
          prepareListData();
  
          listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
  
          // setting list adapter
          expListView.setAdapter(listAdapter);
  
          // Listview Group click listener
          expListView.setOnGroupClickListener(new OnGroupClickListener() {
  
              @Override
              public boolean onGroupClick(ExpandableListView parent, View v,
                      int groupPosition, long id) {
                  // Toast.makeText(getApplicationContext(),
                  // "Group Clicked " + listDataHeader.get(groupPosition),
                  // Toast.LENGTH_SHORT).show();
                  return false;
              }
          });
  
          // Listview Group expanded listener
          expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
  
              @Override
              public void onGroupExpand(int groupPosition) {
                  Toast.makeText(getApplicationContext(),
                          listDataHeader.get(groupPosition) + " Expanded",
                          Toast.LENGTH_SHORT).show();
              }
          });
  
          // Listview Group collasped listener
          expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
  
              @Override
              public void onGroupCollapse(int groupPosition) {
                  Toast.makeText(getApplicationContext(),
                          listDataHeader.get(groupPosition) + " Collapsed",
                          Toast.LENGTH_SHORT).show();
  
              }
          });
  
          // Listview on child click listener
          expListView.setOnChildClickListener(new OnChildClickListener() {
  
              @Override
              public boolean onChildClick(ExpandableListView parent, View v,
                      int groupPosition, int childPosition, long id) {
                  // TODO Auto-generated method stub
                  Toast.makeText(
                          getApplicationContext(),
                          listDataHeader.get(groupPosition)
                                  + " : "
                                  + listDataChild.get(
                                          listDataHeader.get(groupPosition)).get(
                                          childPosition), Toast.LENGTH_SHORT)
                          .show();
                  return false;
              }
          });
      }
  
      /*
       * Preparing the list data
       */
      private void prepareListData() {
          listDataHeader = new ArrayList&lt;String&gt;();
          listDataChild = new HashMap&lt;String, List&lt;String&gt;&gt;();
  
  for (int i=0; i&lt;=10; i++)
          {
              listDataHeader.add("Header"+ i);
  
              // Adding child data
              List&lt;String&gt; child = new ArrayList&lt;String&gt;();
              child.add("Child"+i);
              child.add("Child"+i);
  
              listDataChild.put(listDataHeader.get(i), child); // Header, Child data
  
          }
      }
  
  }
  </code></pre>
  
  <p><strong>ExpandableListAdapter</strong>:</p>
  
  <pre><code>public class ExpandableListAdapter extends BaseExpandableListAdapter {
  
      private Context _context;
      private List&lt;String&gt; _listDataHeader; // header titles
      // child data in format of header title, child title
      private HashMap&lt;String, List&lt;String&gt;&gt; _listDataChild;
  
      public ExpandableListAdapter(Context context, List&lt;String&gt; listDataHeader,
              HashMap&lt;String, List&lt;String&gt;&gt; listChildData) {
          this._context = context;
          this._listDataHeader = listDataHeader;
          this._listDataChild = listChildData;
      }
  
      @Override
      public Object getChild(int groupPosition, int childPosititon) {
          return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                  .get(childPosititon);
      }
  
      @Override
      public long getChildId(int groupPosition, int childPosition) {
          return childPosition;
      }
  
      @Override
      public View getChildView(int groupPosition, final int childPosition,
              boolean isLastChild, View convertView, ViewGroup parent) {
  
          final String childText = (String) getChild(groupPosition, childPosition);
  
          if (convertView == null) {
              LayoutInflater infalInflater = (LayoutInflater) this._context
                      .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              convertView = infalInflater.inflate(R.layout.list_item, null);
          }
  
          TextView txtListChild = (TextView) convertView
                  .findViewById(R.id.lblListItem);
  
          txtListChild.setText(childText);
          return convertView;
      }
  
      @Override
      public int getChildrenCount(int groupPosition) {
          return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                  .size();
      }
  
      @Override
      public Object getGroup(int groupPosition) {
          return this._listDataHeader.get(groupPosition);
      }
  
      @Override
      public int getGroupCount() {
          return this._listDataHeader.size();
      }
  
      @Override
      public long getGroupId(int groupPosition) {
          return groupPosition;
      }
  
      @Override
      public View getGroupView(int groupPosition, boolean isExpanded,
              View convertView, ViewGroup parent) {
          String headerTitle = (String) getGroup(groupPosition);
          if (convertView == null) {
              LayoutInflater infalInflater = (LayoutInflater) this._context
                      .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              convertView = infalInflater.inflate(R.layout.list_group, null);
          }
  
          TextView lblListHeader = (TextView) convertView
                  .findViewById(R.id.lblListHeader);
          lblListHeader.setTypeface(null, Typeface.BOLD);
          lblListHeader.setText(headerTitle);
  
          return convertView;
      }
  
      @Override
      public boolean hasStableIds() {
          return false;
      }
  
      @Override
      public boolean isChildSelectable(int groupPosition, int childPosition) {
          return true;
      }
  
  }
  </code></pre>
  
  <p>How should the achieve the requirement?</p>