For my mobile app MijnLessenrooster I needed a list which contained an other list. Soon I found the ExpandableListView in the Google API. I saw I needed to make my own BaseExpandableListAdapter class to make the list work. Here is my tutorial how to implement a Listview in your android application.
Example ExpandableListView |
I used a linked hashmap to store my data, the keyset is for the headers and the valueset for the second list. You can use whatever you want but in my application I needed a sorted map.
XML files you need to make in the /layout folder
list_view_main.xml
Next is the java files itself. The only thing needed to make this code works is to store your data in the LinkedHashMap "data". An example of the data inside the map:
ExpandableListView.java
XML files you need to make in the /layout folder
- list_view_main.xml
- child_item.xml
list_view_main.xml
<?xml version="1.0" encoding="utf-8"?>child_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ExpandableListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>For this particular application I used the listview inside a fragment. With a few tweaks you could use this as a normal view.
<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/item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="25dp" />
</LinearLayout>
Next is the java files itself. The only thing needed to make this code works is to store your data in the LinkedHashMap "data". An example of the data inside the map:
- item1
- childitem1
- childitem2
- item2
- childitem1
ExpandableListView.java
public class ExpandableListView extends Fragment {
private View rootView;
private Map<String, ArrayList<String>> data =
new LinkedHashMap<String, ArrayList<String>>();
private List<String> groupList;
private List<String> childList;
private Map<String, List<String>> dataCollection;
private LayoutInflater inflater;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.inflater = inflater;
rootView = inflater.inflate(R.layout.list_view_main, null);
// you must fill the linkedhashmap data before this 2 methods
createGroupList();
createCollection();
ExpandableListView elv =
(ExpandableListView) rootView.findViewById(R.id.list);
elv.setAdapter(new ExpandableListAdapter
(inflater, groupList,dataCollection));
return rootView;
}
private void createGroupList() {
groupList = new ArrayList<String>();
for (String groupItem : data.keySet()) {
groupList.add(groupItem);
}
}
private void createCollection() {
dataCollection = new LinkedHashMap<String, List<String>>();
for (String childItem : groupList) {
ArrayList<String> l = data.get(childItem);
loadChild(l.toArray(new String[l.size()]));
dataCollection.put(laptop, childList);
}
}
private void loadChild(String[] childModels) {
childList = new ArrayList<String>();
for (String model : childModels)
childList.add(model);
}
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private LayoutInflater context;
private Map<String, List<String>> dataCollection;
private List<String> childItems;
public ExpandableListAdapter(LayoutInflater context,
List<String> childItems,
Map<String, List<String>> dataCollection) {
this.context = context;
this.dataCollection = dataCollection;
this.childItems = childItems;
}
public Object getChild(int groupPosition, int childPosition) {
return dataCollection.get(childItems.get(groupPosition)).get(
childPosition);
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public View getChildView(final int groupPosition,
final int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
TextView textView = new TextView(
ExpandableListView.this.getActivity());
textView.setText(getChild(groupPosition, childPosition).toString());
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
textView.setPadding(50, 7, 7, 7);
return textView;
}
public int getChildrenCount(int groupPosition) {
return dataCollection.get(childItems.get(groupPosition)).size();
}
public Object getGroup(int groupPosition) {
return childItems.get(groupPosition);
}
public int getGroupCount() {
return childItems.size();
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String childName = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = context;
convertView = infalInflater.inflate(R.layout.child_item, null);
}
TextView item = (TextView) convertView.findViewById(R.id.item);
item.setTypeface(null, Typeface.BOLD);
item.setText(childName);
return convertView;
}
public boolean hasStableIds() {
return true;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
}
I hope this tutorial helped you and if you have any questions feel free to ask them!
what is "laptop"?
ReplyDeletea computer that is portable and suitable for use while travelling.
DeleteThis line not working for me. Any suggestions?
ReplyDeleteTextView textView =
ExpandableListView.this.getActivity());
Thanks
the line is : TextView textView = new TextView(ExpandableListView.this.getActivity());
Deleteafter the equal sigs is NEW ....
hey can u give example of how to store data in LinkedHashMap data ?
ReplyDeletePlease help me ..i'm getting "classcast exception"
ReplyDeletecannot resolve laptop
ReplyDeleteand expandablelistview is not an enclosing type
Dont try... Waste of time, Just See Concept
ReplyDeleteYes Waste of time...Dont try
ReplyDelete