-
-
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; | |
| } | |
| } |
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?

Great solution, thanks!