-
-
Save Psest328/8762232 to your computer and use it in GitHub Desktop.
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import android.annotation.SuppressLint; | |
import android.content.Context; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.BaseExpandableListAdapter; | |
import android.widget.CheckBox; | |
import android.widget.CompoundButton; | |
import android.widget.CompoundButton.OnCheckedChangeListener; | |
import android.widget.TextView; | |
// Eclipse wanted me to use a sparse array instead of my hashmaps, I just suppressed that suggestion | |
@SuppressLint("UseSparseArrays") | |
public class ExpListViewAdapterWithCheckbox extends BaseExpandableListAdapter { | |
// Define activity context | |
private Context mContext; | |
/* | |
* Here we have a Hashmap containing a String key | |
* (can be Integer or other type but I was testing | |
* with contacts so I used contact name as the key) | |
*/ | |
private HashMap<String, List<ExpListChildItems>> mListDataChild; | |
// ArrayList that is what each key in the above | |
// hashmap points to | |
private ArrayList<ExpListGroupItems> mListDataGroup; | |
// Hashmap for keeping track of our checkbox check states | |
private HashMap<Integer, boolean[]> mChildCheckStates; | |
// Our getChildView & getGroupView use the viewholder patter | |
// Here are the viewholders defined, the inner classes are | |
// at the bottom | |
private ChildViewHolder childViewHolder; | |
private GroupViewHolder groupViewHolder; | |
/* | |
* For the purpose of this document, I'm only using a single | |
* textview in the group (parent) and child, but you're limited only | |
* by your XML view for each group item :) | |
*/ | |
private String groupText; | |
private String childText | |
/* Here's the constructor we'll use to pass in our calling | |
* activity's context, group items, and child items | |
*/ | |
public ExpListViewAdapterWithCheckbox(Context context, | |
ArrayList<ExpListGroupItems> listDataGroup, HashMap<String, List<ExpListChildItems>> listDataChild) { | |
mContext = context; | |
mListDataGroup = listDataGroup; | |
mListDataChild = listDataChild; | |
// Initialize our hashmap containing our check states here | |
mChildCheckStates = new HashMap<Integer, boolean[]>(); | |
} | |
@Override | |
public int getGroupCount() { | |
return mListDataGroup.size(); | |
} | |
/* | |
* This defaults to "public object getGroup" if you auto import the methods | |
* I've always make a point to change it from "object" to whatever item | |
* I passed through the constructor | |
*/ | |
@Override | |
public ExpListGroupItems getGroup(int groupPosition) { | |
return mListDataGroup.get(groupPosition); | |
} | |
@Override | |
public long getGroupId(int groupPosition) { | |
return groupPosition; | |
} | |
@Override | |
public View getGroupView(int groupPosition, boolean isExpanded, | |
View convertView, ViewGroup parent) { | |
// I passed a text string into an activity holding a getter/setter | |
// which I passed in through "ExpListGroupItems". | |
// Here is where I call the getter to get that text | |
groupText = getGroup(groupPosition).getMyText(); | |
if (convertView == null) { | |
LayoutInflater inflater = (LayoutInflater) mContext | |
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); | |
convertView = inflater.inflate(R.layout.group_item, null); | |
// Initialize the GroupViewHolder defined at the bottom of this document | |
groupViewHolder = new GroupViewHolder(); | |
groupViewHolder.mGroupText = (TextView) convertView.findViewById(R.id.groupTextView); | |
convertView.setTag(groupViewHolder); | |
} else { | |
groupViewHolder = (GroupViewHolder) convertView.getTag(); | |
} | |
groupViewHolder.mGroupText.setText(groupText); | |
return convertView; | |
} | |
@Override | |
public int getChildrenCount(int groupPosition) { | |
return mListDataChild.get(mListDataGroup.get(groupPosition).getMyText()).size(); | |
} | |
/* | |
* This defaults to "public object getChild" if you auto import the methods | |
* I've always make a point to change it from "object" to whatever item | |
* I passed through the constructor | |
*/ | |
@Override | |
public ExpListChildItems getChild(int groupPosition, int childPosition) { | |
return mListDataChild.get(mListDataGroup.get(groupPosition).getMyText()).get(childPosition); | |
} | |
@Override | |
public long getChildId(int groupPosition, int childPosition) { | |
return childPosition; | |
} | |
@Override | |
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { | |
final int mGroupPosition = groupPosition; | |
final int mChildPosition = childPosition; | |
// I passed a text string into an activity holding a getter/setter | |
// which I passed in through "ExpListChildItems". | |
// Here is where I call the getter to get that text | |
childText = getChild(mGroupPosition, mChildPosition).getChildText(); | |
if (convertView == null) { | |
LayoutInflater inflater = (LayoutInflater) this.mContext | |
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); | |
convertView = inflater.inflate(R.layout.child_item, null); | |
childViewHolder = new ChildViewHolder(); | |
childViewHolder.mChildText = (TextView) convertView | |
.findViewById(R.id.childTextView); | |
childViewHolder.mCheckBox = (CheckBox) convertView | |
.findViewById(R.id.checkBox); | |
convertView.setTag(R.layout.child_item, childViewHolder); | |
} else { | |
childViewHolder = (ChildViewHolder) convertView | |
.getTag(R.layout.child_item); | |
} | |
childViewHolder.mChildText.setText(childText); | |
/* | |
* You have to set the onCheckChangedListener to null | |
* before restoring check states because each call to | |
* "setChecked" is accompanied by a call to the | |
* onCheckChangedListener | |
*/ | |
childViewHolder.mCheckBox.setOnCheckedChangeListener(null); | |
if (mChildCheckStates.containsKey(mGroupPosition)) { | |
/* | |
* if the hashmap mChildCheckStates<Integer, Boolean[]> contains | |
* the value of the parent view (group) of this child (aka, the key), | |
* then retrive the boolean array getChecked[] | |
*/ | |
boolean getChecked[] = mChildCheckStates.get(mGroupPosition); | |
// set the check state of this position's checkbox based on the | |
// boolean value of getChecked[position] | |
childViewHolder.mCheckBox.setChecked(getChecked[mChildPosition]); | |
} else { | |
/* | |
* if the hashmap mChildCheckStates<Integer, Boolean[]> does not | |
* contain the value of the parent view (group) of this child (aka, the key), | |
* (aka, the key), then initialize getChecked[] as a new boolean array | |
* and set it's size to the total number of children associated with | |
* the parent group | |
*/ | |
boolean getChecked[] = new boolean[getChildrenCount(mGroupPosition)]; | |
// add getChecked[] to the mChildCheckStates hashmap using mGroupPosition as the key | |
mChildCheckStates.put(mGroupPosition, getChecked); | |
// set the check state of this position's checkbox based on the | |
// boolean value of getChecked[position] | |
childViewHolder.mCheckBox.setChecked(false); | |
} | |
childViewHolder.mCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { | |
@Override | |
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { | |
if (isChecked) { | |
boolean getChecked[] = mChildCheckStates.get(mGroupPosition); | |
getChecked[mChildPosition] = isChecked; | |
mChildCheckStates.put(mGroupPosition, getChecked); | |
} else { | |
boolean getChecked[] = mChildCheckStates.get(mGroupPosition); | |
getChecked[mChildPosition] = isChecked; | |
mChildCheckStates.put(mGroupPosition, getChecked); | |
} | |
} | |
}); | |
return convertView; | |
} | |
@Override | |
public boolean isChildSelectable(int groupPosition, int childPosition) { | |
return false; | |
} | |
@Override | |
public boolean hasStableIds() { | |
return false; | |
} | |
public final class GroupViewHolder { | |
TextView mGroupText; | |
} | |
public final class ChildViewHolder { | |
TextView mChildText; | |
CheckBox mCheckBox; | |
} | |
} |
What is getGroupText() on line 92?
I guess it should be getMyText()??
thanks !!!
Thanks. Very helpful. 👍
Thank you! that helped a lot!
Great... Thanks !! saved my day :)
Nice.
Many thanks Psest328! I have implemented your code and can see the expandablelistview with checkboxes. How can I check which checkboxes are selected from the MainActivity? I am stuck at this point. Any tipps are greatly appreciated.
P.S.: Do you know of an easy way to adapt your approach in case there is more than one child in a group?
Thanks! I have my own implementation of keeping track of the checked state, but the key factor you helped me with is setting the OnCheckedChangeListener to null before restoring the checkbox state, and then setting the OnCheckedChangedListener for the checkbox.
thanks! but how to set group checkbox position and when i select group checkbox all the child checkbox select.
Great solution, thanks!
on-expand , collapse group then checked checkbox getting unchecked...
Great solution , it is very useful. Thanks!!!
Hi ,Is there any way to store "HashMap<Integer, boolean[]> mChildCheckStates=new HashMap<Integer, boolean[]>();" into shared preferences or any other storage.
Thanks a lot for the example. I just want to know how am I supposed the retrieve the items selected.
thanks man you do useful work
Hey is there a special reason why the same code will be executed on if and else? ^^
`
childViewHolder.mCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
getChecked[mChildPosition] = isChecked;
mChildCheckStates.put(mGroupPosition, getChecked);
} else {
boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
getChecked[mChildPosition] = isChecked;
mChildCheckStates.put(mGroupPosition, getChecked);
}
}
});
`
working example would be to helpful if anybody have.
HI i am new in development, can anybody share the xml to use. thanks in advance to all.
Hi, I want to getText of selected items, Can anyone please help with this?
Hello nice code, works like a charm. But I have a question, for you what is the difference between getChildText() and getMyText() methods? if there is any