-
-
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!