I want to create an expandable listview with checkboxes present in the groups as well as the children. What I want is, the user may check the group in order to select all the children in the group, or the user may select a particular item under the expandable listview.
This concept is running in our asp.net website as a tree view. I am attaching some screens of the running website:
Treeview with groups unexpanded
Treeview with full group selected
Treeview with particular children selected under group
The main class:
public class MainActivity extends Activity {
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> 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<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("Top 250");
listDataHeader.add("Now Showing");
listDataHeader.add("Coming Soon..");
// Adding child data
List<String> top250 = new ArrayList<String>();
top250.add("The Shawshank Redemption");
top250.add("The Godfather");
top250.add("The Godfather: Part II");
top250.add("Pulp Fiction");
top250.add("The Good, the Bad and the Ugly");
top250.add("The Dark Knight");
top250.add("12 Angry Men");
List<String> nowShowing = new ArrayList<String>();
nowShowing.add("The Conjuring");
nowShowing.add("Despicable Me 2");
nowShowing.add("Turbo");
nowShowing.add("Grown Ups 2");
nowShowing.add("Red 2");
nowShowing.add("The Wolverine");
List<String> comingSoon = new ArrayList<String>();
comingSoon.add("2 Guns");
comingSoon.add("The Smurfs 2");
comingSoon.add("The Spectacular Now");
comingSoon.add("The Canyons");
comingSoon.add("Europa Report");
listDataChild.put(listDataHeader.get(0), top250); // Header, Child data
listDataChild.put(listDataHeader.get(1), nowShowing);
listDataChild.put(listDataHeader.get(2), comingSoon);
}
}
The ExpandableListAdapter:
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> 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;
}
}
The activity_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"
android:background="#f4f4f4" >
<ExpandableListView
android:id="@+id/lvExp"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:cacheColorHint="#00000000"/>
</LinearLayout>
The list_group.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="wrap_content"
android:orientation="vertical"
android:padding="8dp"
android:background="#000000">
<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="#f9f93d" />
</LinearLayout>
The list_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="55dip"
android:orientation="vertical" >
<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:textColor="#000000"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" />
</LinearLayout>
I have already created a simple expandable listview, now I want to include the checkboxes or any other controls to suffice my requirement. I have googled for a sutaible tutorial but I was unable to find one. Please help me with one if possible.
To do this you will need to include boolean
flag in each object, or in you adapter create two list views (for groups and items) that will contain selected items.
I would rather add boolean
like this :
class Group{ ...
boolean isSelected;
}
class Item { ...
boolean isSelected;
}
Then in Adapter
in getViews()
methods:
getItemView(...){
...
itemHolder.checkbox.setSelected(item.isSelected)
}
getGroupView(...){
...
groupHolder.checkbox.setSelected(group.isSelected)
//add lisener
itemHolder.checkbox.setOnCheckedChangeListener(lisener);
}
And on group check you can do something like this :
void selectGroup(Group group){
for(Item item: group.getItems()){
item.isSelected = true;
}
//update your list
notifiDataSetChanged();
}
That's all what you need
UPDATE :
Try this sample Code Expandable CheckList
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With