0

I am a newbie in Android. I want to understand the Expandable ListView implementation using custom adapter. Someone please explain this code to me so I could be able to manipulate it. I have certain questions in mind like why the variable 'groupStatus' is taken as an array variable, cant we just put textview in child node of expandable list etc. Thanks in advance.

public class ExpandableListAdapter extends BaseExpandableListAdapter {

private Context mContext;
private ExpandableListView mExpandableListView;
private List<GroupEntity> mGroupCollection;
private int[] groupStatus;

public ExpandableListAdapter(Context pContext, ExpandableListView pExpandableListView, List<GroupEntity> pGroupCollection) {
 mContext = pContext;
 mGroupCollection = pGroupCollection;
 mExpandableListView = pExpandableListView;
 groupStatus = new int[mGroupCollection.size()];

setListEvent();
 }

private void setListEvent() {

mExpandableListView.setOnGroupExpandListener(new OnGroupExpandListener() {

@Override
 public void onGroupExpand(int arg0) {
 // TODO Auto-generated method stub
 groupStatus[arg0] = 1;
 }
 });

mExpandableListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {

@Override
 public void onGroupCollapse(int arg0) {
 // TODO Auto-generated method stub
 groupStatus[arg0] = 0;
 }
});
}

@Override
public String getChild(int arg0, int arg1) {
// TODO Auto-generated method stub
return mGroupCollection.get(arg0).GroupItemCollection.get(arg1).Name;
}

@Override
 public long getChildId(int arg0, int arg1) {
 // TODO Auto-generated method stub
 return 0;
 }

@Override
 public View getChildView(int arg0, int arg1, boolean arg2, View arg3,
 ViewGroup arg4) {
 // TODO Auto-generated method stub

ChildHolder childHolder;
 if (arg3 == null) {
 arg3 = LayoutInflater.from(mContext).inflate(
 R.layout.list_group_item, null);

childHolder = new ChildHolder();

childHolder.title = (TextView) arg3.findViewById(R.id.item_title);
arg3.setTag(childHolder);
 }else {
 childHolder = (ChildHolder) arg3.getTag();
 }

   childHolder.title.setText(mGroupCollection.get(arg0).GroupItemCollection.get(arg1).Name);

 return arg3;
 }

@Override
 public int getChildrenCount(int arg0) {
 // TODO Auto-generated method stub
 return mGroupCollection.get(arg0).GroupItemCollection.size();
 }

@Override
 public Object getGroup(int arg0) {
 // TODO Auto-generated method stub
 return mGroupCollection.get(arg0);
}

@Override
 public int getGroupCount() {
  // TODO Auto-generated method stub
 return mGroupCollection.size();
 }

@Override
 public long getGroupId(int arg0) {
// TODO Auto-generated method stub
 return arg0;
 }

@Override
 public View getGroupView(int arg0, boolean arg1, View arg2, ViewGroup arg3) {
 // TODO Auto-generated method stub
 GroupHolder groupHolder;
 if (arg2 == null) {
arg2 = LayoutInflater.from(mContext).inflate(R.layout.list_group,
 null);
groupHolder = new GroupHolder();
groupHolder.img = (ImageView) arg2.findViewById(R.id.tag_img);
groupHolder.title = (TextView) arg2.findViewById(R.id.group_title);
 arg2.setTag(groupHolder);
} else {
groupHolder = (GroupHolder) arg2.getTag();
}
if (groupStatus[arg0] == 0) {
groupHolder.img.setImageResource(R.drawable.group_down);
} else {
groupHolder.img.setImageResource(R.drawable.group_up);
}
groupHolder.title.setText(mGroupCollection.get(arg0).Name);

return arg2;
}

class GroupHolder {
 ImageView img;
 TextView title;
 }

class ChildHolder {
 TextView title;
 }

@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}

@Override
public boolean isChildSelectable(int arg0, int arg1) {
// TODO Auto-generated method stub
return true;
}

}
Divyang
  • 372
  • 1
  • 5
  • 21
  • I have gone through this tutorial but was not clear enough.. http://shenhengbin.wordpress.com/2012/03/25/android-practice-custom-expandablelistview-sample-2/ – Divyang Jun 27 '13 at 07:18
  • i would like to example you the concept but can u plz let me know what is ur requirement ? is ur requirement same as the above code says? – KOTIOS Jun 27 '13 at 07:42
  • I want to make an expandable list of categories. On clicking a category user will see the textview explaining the category and includes a button to open another activity. Each category option will consist of the same layout,ie, a textview and a button. and i want to understand how this code is working...and thanku very much for ur cooperation Android28.. – Divyang Jun 27 '13 at 07:52

1 Answers1

3

ExpandableListView in Android

This Android Expandable List View requires three layout files; one for displaying the main layout containing the ExpandableListView, one for group item layout and other for child item layout.

activity_main.xml

<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"
    tools:context=".MainActivity" >

    <ExpandableListView
        android:id="@+id/my_list"
        android:layout_width="match_parent"
        android:layout_height="fill_parent" >
    </ExpandableListView>

</RelativeLayout>

group_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="match_parent"
    android:orientation="vertical"
    android:padding="10dp" >

    <TextView
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="25dp"/>
</LinearLayout>

child_item.xml

According to ur requirement u need a button and textview in child view

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dp" >

    <TextView
        android:id="@+id/child_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:paddingLeft="25dp"
        android:text="child_item" />

    <Button
        android:id="@+id/button1"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="51dp"
        android:layout_toRightOf="@+id/laptop"
        android:text="Button" />

</RelativeLayout>

Each child item contains one TextView to display text and one button to delete item.

Now lets make a class ExpandableListAdapter.java

public class ExpandableListAdapter extends BaseExpandableListAdapter {

    // Variable Declartion
    private Activity context;

    // 1st parameter is the name of Item
    // 2nd parameter is the child's of that of particular Item
    private Map<String, List<String>> itemCollections;

    // here parameter is the name of Item
    private List<String> item;

    // here is the constructor
    // here we just inilize the class variable with the variable you passed to
    // this adapter
    public ExpandableListAdapter(Activity context, List<String> item_names,
            Map<String, List<String>> Collections) {
        this.context = context;
        this.itemCollections = Collections;
        this.item = item_names;
    }

    // if we want to get any child Object from its position this method will
    // provide the same . for example if i click 1st item in group1 and 1st item
    // in its childlist then in this case method will be like getChild(1, 1);
     @Override
    public Object getChild(int groupPosition, int childPosition) {
        // 1. we get the Actuall group clicked -> item.get(groupPosition)
        // 2. we get the child of its ->
        // item.get(groupPosition).get(childPosition)
        // 3. we return it as object from its collection ->
        // itemCollections.get(item.get(groupPosition)).get(childPosition);
        return itemCollections.get(item.get(groupPosition)).get(childPosition);
    }

    // when the child item is clicked this method will be called and it's will
    // return its id
     @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    // here is where we put all data u passed to adapter to its view
     @Override
    public View getChildView(final int groupPosition, final int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {

        LayoutInflater inflater = context.getLayoutInflater();

        // get the layout of child and convertView will hold its instance
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.child_item, null);
        }

        // referance of textview in child layout
        TextView item1 = (TextView) convertView.findViewById(R.id.child_text);
        // referance of button in child layout
        Button delete = (Button) convertView.findViewById(R.id.button1);
        // on click of the button do whatever u want
        delete.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                // do whatever u want
            }
        });

        return convertView;
    }

    // here its provide the total child to be placed into particular group
     @Override
    public int getChildrenCount(int groupPosition) {
        return itemCollections.get(item.get(groupPosition)).size();
    }

    // here we provide the group object itself from its position
     @Override
    public Object getGroup(int groupPosition) {
        return item.get(groupPosition);
    }

    // the size of group items
     @Override
    public int getGroupCount() {
        return item.size();
    }

    // provide id of group on which it is clicked
     @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {
        String itemName = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.group_item, null);
        }
        TextView item = (TextView) convertView.findViewById(R.id.group);
        // here u can set data to item variable that is text view of group
        // layout
        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        // TODO Auto-generated method stub
        return false;
    }

}
KOTIOS
  • 11,177
  • 3
  • 39
  • 66
  • i hope my comments in code will help u understand what i mean i have found one more tutorial for you http://theopentutorials.com/tutorials/android/listview/android-expandable-list-view-example/ ..i think this will help u more better ..try refering it let me know if any issues – KOTIOS Jun 27 '13 at 10:55
  • Thank you so much for the help...a 100 likes for that – Divyang Jun 27 '13 at 11:44
  • Any more questions appricated – KOTIOS Jun 27 '13 at 11:53
  • and one more thing, why have you used Map? – Divyang Jun 27 '13 at 13:51
  • also what would be the difference between if we had taken Context class in place of Activity class...at line "private Activity context"? – Divyang Jun 27 '13 at 14:03
  • 1. I used Map since in my code i want to have unique keys. u can u use collection what u want 2. for ur second question refer this http://stackoverflow.com/questions/6518206/what-is-the-difference-between-activity-and-context – KOTIOS Jun 27 '13 at 16:25
  • Thanks...that were some fine answers... I have to pass intents to start new activity on clicking buttons of child. for eg: on clicking the item 1 of expandable listview it expands and show the child of item. The child consists of a button, say "Explore Tours". By clicking on explore tours i want to open a new activity ExploreTourActivity.class. I m unable to accomplish that.. Please Help..Thanks in advance – Divyang Jun 28 '13 at 06:19
  • in the onclick method of expandablelistadapter i have intialised intent as "Intent i1 = new Intent(this, MainActivity.class); startactivity(i1);" but it is giving error that constructor Intent(ExpaldableListAdapter, class) is undefined...wat to do? – Divyang Jun 28 '13 at 08:48
  • hey adapter is just for filling the data in expandable list view ..u have to call this adapter class in ur Activity class..REMEMBER[u can use intent from one activity to other & NOT FROM ADAPTER TO ACTIVITY] – KOTIOS Jun 28 '13 at 09:10
  • ohk..thanks i wasnt aware of that..so where in activity should I place button click code..as the onclick method is in adapter class.. – Divyang Jun 28 '13 at 09:37