I have 500+ items to put in a checklist divided into categories. My solution so far for this is to use multiple expandableListView lists and the items inside them of course. The problem shows up when I check some of the check boxes, the get messed up and check boxes from another lists get checked and I dont know why.. Can someone throw some light here?
ExpandableListView.java
public class IngredientsExpandableList extends ExpandableListActivity {
// Create ArrayList to hold parent Items and Child Items
private ArrayList<ParentModel> parentItems = new ArrayList<ParentModel>();
private ArrayList<ChildModel> childItems = new ArrayList<ChildModel>();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create Expandable List and set it's properties
ExpandableListView expandableList = getExpandableListView();
expandableList.setDividerHeight(0);
expandableList.setGroupIndicator(null);
expandableList.setClickable(true);
//Setting the data.
setData();
// Create the Adapter
MyExpandableAdapter adapter = new MyExpandableAdapter(parentItems, childItems);
adapter.setInflater(LayoutInflater.from(this), this);
// Set the Adapter to expandableList
expandableList.setAdapter(adapter);
expandableList.setOnChildClickListener(this);
}
public void setData(){
String[] colors = getResources().getStringArray(R.array.ingredientsColor);
String[] innerColors = getResources().getStringArray(R.array.ingredientsInnerColor);
// Set the Items of Parent
for (int i = 0; i < 10; i++){
parentItems.add(new ParentModel("ingredients "+(i+1), Color.parseColor(colors[i])));
}
// Set The Child Data
ArrayList<String> child = null;
for (int i = 0; i < parentItems.size(); i++){
child = new ArrayList<String>();
for (int k = 0; k < 4; k++){
child.add("ingredient " + (k+1));
}
childItems.add(new ChildModel(child,Color.parseColor(innerColors[i])));
}
}
public void makeToast(String string){
Toast.makeText(this, string,
Toast.LENGTH_SHORT).show();
}
public class ParentModel{
String text;
int color;
public ParentModel(String text, int color) {
this.text = text;
this.color = color;
}
public String getText() {
return text;
}
public int getColor() {
return color;
}
}
public class ChildModel{
ArrayList<String> text;
int color;
public ChildModel(ArrayList<String> text, int color) {
this.text = text;
this.color = color;
}
public ArrayList<String> getText() {
return text;
}
public int getColor() {
return color;
}
}
public class MyExpandableAdapter extends BaseExpandableListAdapter
{
private Activity activity;
private ArrayList<ChildModel> childItems;
private LayoutInflater inflater;
private ArrayList<ParentModel> parentItems;
private ArrayList<String> child;
// constructor
public MyExpandableAdapter(ArrayList<ParentModel> parents, ArrayList<ChildModel> childern)
{
this.parentItems = parents;
this.childItems = childern;
}
public void setInflater(LayoutInflater inflater, Activity activity)
{
this.inflater = inflater;
this.activity = activity;
}
// method getChildView is called automatically for each child view.
// Implement this method as per your requirement
@Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent)
{
child = childItems.get(groupPosition).getText();
TextView textView = null;
CheckBox checkBox = null;
LinearLayout LinearView = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.child_list, null);
}
// get the textView reference and set the value
textView = (TextView) convertView.findViewById(R.id.textView1);
textView.setText(child.get(childPosition));
LinearView = (LinearLayout) convertView.findViewById(R.id.layout);
LinearView.setBackgroundColor(childItems.get(groupPosition).getColor());
checkBox = (CheckBox) convertView.findViewById(R.id.checkBox1);
// set the ClickListener to handle the click event on child item
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
makeToast("clicked");
}
});
return convertView;
}
// method getGroupView is called automatically for each parent item
// Implement this method as per your requirement
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
if (convertView == null) {
convertView = inflater.inflate(R.layout.parent_list, null);
}
((CheckedTextView) convertView.findViewById(R.id.textViewGroup)).setText(parentItems.get(groupPosition).getText());
((CheckedTextView) convertView.findViewById(R.id.textViewGroup)).setBackgroundColor(parentItems.get(groupPosition).getColor());
((CheckedTextView) convertView.findViewById(R.id.textViewGroup)).setChecked(isExpanded);
return convertView;
}
@Override
public Object getChild(int groupPosition, int childPosition)
{
return null;
}
@Override
public long getChildId(int groupPosition, int childPosition)
{
return 0;
}
@Override
public int getChildrenCount(int groupPosition)
{
return childItems.get(groupPosition).getText().size();
}
@Override
public Object getGroup(int groupPosition)
{
return null;
}
@Override
public int getGroupCount()
{
return parentItems.size();
}
@Override
public void onGroupCollapsed(int groupPosition)
{
super.onGroupCollapsed(groupPosition);
}
@Override
public void onGroupExpanded(int groupPosition)
{
super.onGroupExpanded(groupPosition);
}
@Override
public long getGroupId(int groupPosition)
{
return 0;
}
@Override
public boolean hasStableIds()
{
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition)
{
return false;
}
}
}
This is because views are recycled in lists so you must store the state of the checks and make sure you set them inside the get child view. something like this
public class IngredientsExpandableList extends ExpandableListActivity {
// Create ArrayList to hold parent Items and Child Items
private ArrayList<ParentModel> parentItems = new ArrayList<ParentModel>();
private ArrayList<ChildModel> childItems = new ArrayList<ChildModel>();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create Expandable List and set it's properties
ExpandableListView expandableList = getExpandableListView();
expandableList.setDividerHeight(0);
expandableList.setGroupIndicator(null);
expandableList.setClickable(true);
//Setting the data.
setData();
// Create the Adapter
MyExpandableAdapter adapter = new MyExpandableAdapter(parentItems, childItems);
adapter.setInflater(LayoutInflater.from(this), this);
// Set the Adapter to expandableList
expandableList.setAdapter(adapter);
expandableList.setOnChildClickListener(this);
}
public void setData(){
String[] colors = getResources().getStringArray(R.array.ingredientsColor);
String[] innerColors = getResources().getStringArray(R.array.ingredientsInnerColor);
// Set the Items of Parent
for (int i = 0; i < 10; i++){
parentItems.add(new ParentModel("ingredients "+(i+1), Color.parseColor(colors[i])));
}
// Set The Child Data
ArrayList<String> child = null;
for (int i = 0; i < parentItems.size(); i++){
child = new ArrayList<String>();
for (int k = 0; k < 4; k++){
child.add("ingredient " + (k+1));
}
childItems.add(new ChildModel(child,Color.parseColor(innerColors[i])));
}
}
public void makeToast(String string){
Toast.makeText(this, string,
Toast.LENGTH_SHORT).show();
}
public class ParentModel{
String text;
int color;
public ParentModel(String text, int color) {
this.text = text;
this.color = color;
}
public String getText() {
return text;
}
public int getColor() {
return color;
}
}
public class ChildModel{
ArrayList<String> text;
int color;
ArrayList<Boolean> checked = new ArrayList();;
public ChildModel(ArrayList<String> text, int color) {
this.text = text;
this.color = color;
for(String i:text)
{
checked.add(false);
}
}
public ArrayList<String> getText() {
return text;
}
public int getColor() {
return color;
}
}
public class MyExpandableAdapter extends BaseExpandableListAdapter
{
private Activity activity;
private ArrayList<ChildModel> childItems;
private LayoutInflater inflater;
private ArrayList<ParentModel> parentItems;
private ArrayList<String> child;
// constructor
public MyExpandableAdapter(ArrayList<ParentModel> parents, ArrayList<ChildModel> childern)
{
this.parentItems = parents;
this.childItems = childern;
}
public void setInflater(LayoutInflater inflater, Activity activity)
{
this.inflater = inflater;
this.activity = activity;
}
// method getChildView is called automatically for each child view.
// Implement this method as per your requirement
@Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent)
{
child = childItems.get(groupPosition).getText();
TextView textView = null;
CheckBox checkBox = null;
LinearLayout LinearView = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.child_list, null);
}
// get the textView reference and set the value
textView = (TextView) convertView.findViewById(R.id.textView1);
textView.setText(child.get(childPosition));
LinearView = (LinearLayout) convertView.findViewById(R.id.layout);
LinearView.setBackgroundColor(childItems.get(groupPosition).getColor());
checkBox = (CheckBox) convertView.findViewById(R.id.checkBox1);
checkBox.setChecked(childItems.get(groupPosition).checked.get(childPosition));
checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
childItems.get(groupPosition).checked.get(childPosition) = isChecked;
}
});
// set the ClickListener to handle the click event on child item
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
makeToast("clicked");
}
});
return convertView;
}
// method getGroupView is called automatically for each parent item
// Implement this method as per your requirement
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
if (convertView == null) {
convertView = inflater.inflate(R.layout.parent_list, null);
}
((CheckedTextView) convertView.findViewById(R.id.textViewGroup)).setText(parentItems.get(groupPosition).getText());
((CheckedTextView) convertView.findViewById(R.id.textViewGroup)).setBackgroundColor(parentItems.get(groupPosition).getColor());
((CheckedTextView) convertView.findViewById(R.id.textViewGroup)).setChecked(isExpanded);
return convertView;
}
@Override
public Object getChild(int groupPosition, int childPosition)
{
return null;
}
@Override
public long getChildId(int groupPosition, int childPosition)
{
return 0;
}
@Override
public int getChildrenCount(int groupPosition)
{
return childItems.get(groupPosition).getText().size();
}
@Override
public Object getGroup(int groupPosition)
{
return null;
}
@Override
public int getGroupCount()
{
return parentItems.size();
}
@Override
public void onGroupCollapsed(int groupPosition)
{
super.onGroupCollapsed(groupPosition);
}
@Override
public void onGroupExpanded(int groupPosition)
{
super.onGroupExpanded(groupPosition);
}
@Override
public long getGroupId(int groupPosition)
{
return 0;
}
@Override
public boolean hasStableIds()
{
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition)
{
return false;
}
}
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