I've read about 30 pages from SO as well as tutorials about tracking check states in lists but info (especially working info) is scarce on doing so in an Expandable ListView.
I've got the children populating with checkboxes but when I check a box on a child from 1 group, random children in other groups also check. I need to stop this. The best info I think I read was to set the checkbox as a separate tag but I don't know how to set multiple tags, when I tried, I got a class mismatch error comparing the checkbox to the convertview.
Has anybody come across a good way to keep track of checkbox states in an expandablelistview's children?
I've made multiple changes so I'm putting in the entire adapter code. Please check first few lines of getGroupView and entire getChildView and help me see what I'm doing wrong.
EDIT:
What's happening now is that when I check a box and then expand another group, all checked boxes uncheck:
public class MyExpandableListAdapter extends BaseExpandableListAdapter
implements OnCheckedChangeListener {
private Context mContext;
private ArrayList<ContactNameItems> mListDataHeader;
private HashMap<String, List<ContactPhoneItems>> mListDataChild;
private boolean[] mGetChecked;
private HashMap<String, boolean[]> mChildCheckStates;
private ArrayList<String> selectedNumbers;
private ChildViewHolder childViewHolder;
private GroupViewHolder groupViewHolder;
private String numberText;
public MyExpandableListAdapter(Context context,
ArrayList<ContactNameItems> listDataHeader,
HashMap<String, List<ContactPhoneItems>> listDataChild,
ArrayList<String> listOfNumbers) {
mContext = context;
mListDataHeader = listDataHeader;
mListDataChild = listDataChild;
selectedNumbers = listOfNumbers;
mChildCheckStates = new HashMap<String, boolean[]>();
}
#Override
public int getGroupCount() {
return mListDataHeader.size();
}
#Override
public ContactNameItems getGroup(int groupPosition) {
return mListDataHeader.get(groupPosition);
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String contactName = getGroup(groupPosition).getName();
Bitmap contactImage = getGroup(groupPosition).getImage();
mGetChecked = new boolean[getChildrenCount(groupPosition)];
mChildCheckStates.put(contactName, mGetChecked);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.contact_name_item, null);
groupViewHolder = new GroupViewHolder();
groupViewHolder.mContactName = (TextView) convertView
.findViewById(R.id.lblListHeader);
groupViewHolder.mContactImage = (ImageView) convertView
.findViewById(R.id.ivContactPhoto);
convertView.setTag(groupViewHolder);
} else {
groupViewHolder = (GroupViewHolder) convertView.getTag();
}
if (contactImage != null) {
groupViewHolder.mContactImage.setImageBitmap(contactImage);
} else {
groupViewHolder.mContactImage
.setImageResource(R.drawable.default_contact);
}
groupViewHolder.mContactName.setText(contactName);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return mListDataChild.get(mListDataHeader.get(groupPosition).getName())
.size();
}
#Override
public ContactPhoneItems getChild(int groupPosition, int childPosition) {
return mListDataChild.get(mListDataHeader.get(groupPosition).getName())
.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 String contactName = getGroup(groupPosition).getName();
final int mChildPosition = childPosition;
numberText = getChild(groupPosition, childPosition).getNumber();
String typeText = getChild(groupPosition, childPosition).getPhoneType();
mGetChecked = mChildCheckStates.get(contactName);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this.mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.contact_detail_item, null);
childViewHolder = new ChildViewHolder();
childViewHolder.mPhoneNumber = (TextView) convertView
.findViewById(R.id.tv_phone_number);
childViewHolder.mPhoneType = (TextView) convertView
.findViewById(R.id.tv_phone_type);
childViewHolder.mCheckBox = (CheckBox) convertView
.findViewById(R.id.checkBox);
convertView.setTag(R.layout.contact_detail_item, childViewHolder);
} else {
childViewHolder = (ChildViewHolder) convertView
.getTag(R.layout.contact_detail_item);
}
childViewHolder.mPhoneNumber.setText(numberText);
childViewHolder.mPhoneType.setText(typeText);
childViewHolder.mCheckBox.setChecked(mGetChecked[mChildPosition]);
childViewHolder.mCheckBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
boolean isChecked = childViewHolder.mCheckBox.isChecked();
Log.d("Debug", "isChecked = " + String.valueOf(isChecked));
if (isChecked) {
selectedNumbers.add(numberText);
} else {
selectedNumbers.remove(numberText);
}
childViewHolder.mCheckBox.setChecked(isChecked);
mGetChecked[mChildPosition] = isChecked;
mChildCheckStates.put(contactName, mGetChecked);
}
});
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
#Override
public boolean hasStableIds() {
return false;
}
public ArrayList<String> getSelectedNumbers() {
return selectedNumbers;
}
public final class GroupViewHolder {
TextView mContactName;
ImageView mContactImage;
}
public final class ChildViewHolder {
TextView mPhoneNumber;
TextView mPhoneType;
CheckBox mCheckBox;
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
Log.d("Debug", "onCheckChangedListener : " + String.valueOf(isChecked));
}
}
HERE IS THE WORKING SOLUTION
OK, although there seems to be a lot of suggestions on the internet about checkboxes in expandable listviews, none had worked for me. I was able to get it working with the help of a bunch of people, especially anddev84. Now I'm not going to claim that this is perfect or foolproof. I'm just claiming that it works for me. I've tested on 2 devices and I'm very pleased with it.
So I've taken my working code, dwindled it down to its essential parts and added a bunch of helpful comments so anybody who needs it can you it. Hopefully it works as well for you as it does for me. Enjoy
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 MyExpandableListAdapter 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 MyExpandableListAdapter(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 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).getGroupText();
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 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;
}
}
I see you have a selectedNumbers object, what type of collection is that? It might make most sense to have a Map or List or some collection based on something more unique, like the group & child position. Then you can do this:
(EDIT: edited the code to make sure the checkedChangedListener doesn't trigger)
(EDIT 2 based on OP's update): You probably shouldn't use a map of Strings to boolean arrays. Instead try this. It's fairly similar but uses ints which will be more foolproof to compare than Strings
...
HashMap<Integer, Integer> mCheckedStates; // assume initialized as you did
...
childViewHolder.mPhoneNumber.setText(numberText);
childViewHolder.mPhoneType.setText(typeText);
childViewHolder.mCheckBox.setOnCheckedChangeListener(null);
if (mCheckedStates.contains(groupPosition)) {
int checkedChildren = mCheckedStates.get(groupPosition);
if ((checkedChildren & (1 << childPosition)) == 1) {
childViewHolder.mCheckBox.setChecked(true);
} else {
//Edit: Cannot rely on checkbox being false on Recycle,
childViewHolder.mCheckBox.setChecked(false);
}
}
childViewHolder.mCheckBox.setOnCheckedChangeListener(this);
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// get group and child positions
if (isChecked) {
if (mCheckedStates.contains(groupPosition)) {
// I'm using a bitmap to keep resources low, but it's not necessary to do it this way
int childmap = mCheckedStates.get(groupPosition);
childmap += (1 << childPosition);
mCheckedStates.put(groupPosition, childmap);
} else {
mCheckedStates.put(groupPosition, (1 << childPosition));
}
} else {
if (mCheckedStates.contains(groupPosition)) {
int childmap = mCheckedStates.get(groupPosition);
if (childmap == (1 << childPosition)) {
mCheckedStates.remove(groupPosition);
} else {
childmap &= ~(1 << childPosition);
mCheckedStates.put(groupPosition, childmap);
}
}
}
}
}
I was also the victim of the same problem and tried your solution and now its working like a charm. Thanks buddy. :)
I just modified the code with String instead of custom domain model for the ease of other people.
MainActivity.java
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;
public class MainActivity extends Activity {
List<String> groupList;
List<String> childList;
Map<String, List<String>> laptopCollection;
ExpandableListView expListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("-Test Exapansion-", "Nai Yara");
createGroupList();
createCollection();
expListView = (ExpandableListView) findViewById(R.id.laptop_list);
final MyExpandableListAdapter expListAdapter = new MyExpandableListAdapter
(getApplicationContext() ,
groupList, laptopCollection);
expListView.setAdapter(expListAdapter);
expListView.getHeaderViewsCount();
//expListView.expandGroup(1);
//expListView.expandGroup(2);
int numberOfHeaders = expListView.getExpandableListAdapter().getGroupCount();
Log.d("-Test Exapansion-", "Number of Groups are:"+numberOfHeaders);
for(int i = 0; i<numberOfHeaders; i++){
expListView.expandGroup(i);
}
setGroupIndicatorToRight();
expListView.setOnChildClickListener(new OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
final String selected = (String) expListAdapter.getChild(
groupPosition, childPosition);
Toast.makeText(getBaseContext(), selected, Toast.LENGTH_LONG)
.show();
return true;
}
});
}
private void createGroupList() {
groupList = new ArrayList<String>();
groupList.add("HP");
groupList.add("Dell");
groupList.add("Lenovo");
groupList.add("Sony");
groupList.add("HCL");
groupList.add("Samsung");
groupList.add("HTC");
}
private void createCollection() {
// preparing laptops collection(child)
String[] hpModels = { "HP Pavilion G6-2014TX", "ProBook HP 4540",
"HP Envy 4-1025TX" };
String[] hclModels = { "HCL S2101", "HCL L2102", "HCL V2002" };
String[] lenovoModels = { "IdeaPad Z Series", "Essential G Series",
"ThinkPad X Series", "Ideapad Z Series" };
String[] sonyModels = { "VAIO E Series", "VAIO Z Series",
"VAIO S Series", "VAIO YB Series" };
String[] dellModels = { "Inspiron", "Vostro", "XPS" };
String[] samsungModels = { "NP Series", "Series 5", "SF Series" };
String[] hTcModels = { "One", "One X", "Desire Series" };
laptopCollection = new LinkedHashMap<String, List<String>>();
for (String laptop : groupList) {
if (laptop.equals("HP")) {
loadChild(hpModels);
} else if (laptop.equals("Dell"))
loadChild(dellModels);
else if (laptop.equals("Sony"))
loadChild(sonyModels);
else if (laptop.equals("HCL"))
loadChild(hclModels);
else if (laptop.equals("Samsung"))
loadChild(samsungModels);
else if (laptop.equals("HTC"))
loadChild(hTcModels);
else
loadChild(lenovoModels);
laptopCollection.put(laptop, childList);
}
}
private void loadChild(String[] laptopModels) {
childList = new ArrayList<String>();
for (String model : laptopModels)
childList.add(model);
}
private void setGroupIndicatorToRight() {
/* Get the screen width */
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
expListView.setIndicatorBounds(width - getDipsFromPixel(35), width
- getDipsFromPixel(5));
}
// Convert pixel to dip
public int getDipsFromPixel(float pixels) {
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 0.5f);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
MyExpandableListAdapter.java
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;
public class MainActivity extends Activity {
List<String> groupList;
List<String> childList;
Map<String, List<String>> laptopCollection;
ExpandableListView expListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("-Test Exapansion-", "Nai Yara");
createGroupList();
createCollection();
expListView = (ExpandableListView) findViewById(R.id.laptop_list);
final MyExpandableListAdapter
expListAdapter =
new MyExpandableListAdapter(getApplicationContext()
, groupList, laptopCollection);
expListView.setAdapter(expListAdapter);
expListView.getHeaderViewsCount();
int numberOfHeaders = expListView.getExpandableListAdapter().getGroupCount();
Log.d("-Test Exapansion-", "Number of Groups are:"+numberOfHeaders);
for(int i = 0; i<numberOfHeaders; i++){
expListView.expandGroup(i);
}
setGroupIndicatorToRight();
expListView.setOnChildClickListener(new OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
final String selected = (String) expListAdapter.getChild(
groupPosition, childPosition);
Toast.makeText(getBaseContext(), selected, Toast.LENGTH_LONG)
.show();
return true;
}
});
}
private void createGroupList() {
groupList = new ArrayList<String>();
groupList.add("HP");
groupList.add("Dell");
groupList.add("Lenovo");
groupList.add("Sony");
groupList.add("HCL");
groupList.add("Samsung");
groupList.add("HTC");
}
private void createCollection() {
// preparing laptops collection(child)
String[] hpModels = { "HP Pavilion G6-2014TX", "ProBook HP 4540",
"HP Envy 4-1025TX" };
String[] hclModels = { "HCL S2101", "HCL L2102", "HCL V2002" };
String[] lenovoModels = { "IdeaPad Z Series", "Essential G Series",
"ThinkPad X Series", "Ideapad Z Series" };
String[] sonyModels = { "VAIO E Series", "VAIO Z Series",
"VAIO S Series", "VAIO YB Series" };
String[] dellModels = { "Inspiron", "Vostro", "XPS" };
String[] samsungModels = { "NP Series", "Series 5", "SF Series" };
String[] hTcModels = { "One", "One X", "Desire Series" };
laptopCollection = new LinkedHashMap<String, List<String>>();
for (String laptop : groupList) {
if (laptop.equals("HP")) {
loadChild(hpModels);
} else if (laptop.equals("Dell"))
loadChild(dellModels);
else if (laptop.equals("Sony"))
loadChild(sonyModels);
else if (laptop.equals("HCL"))
loadChild(hclModels);
else if (laptop.equals("Samsung"))
loadChild(samsungModels);
else if (laptop.equals("HTC"))
loadChild(hTcModels);
else
loadChild(lenovoModels);
laptopCollection.put(laptop, childList);
}
}
private void loadChild(String[] laptopModels) {
childList = new ArrayList<String>();
for (String model : laptopModels)
childList.add(model);
}
private void setGroupIndicatorToRight() {
/* Get the screen width */
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
expListView.setIndicatorBounds(width - getDipsFromPixel(35), width
- getDipsFromPixel(5));
}
// Convert pixel to dip
public int getDipsFromPixel(float pixels) {
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 0.5f);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
The problem is you use positions as ids. Position is not a id. Position may change and position of a child without group position is not unique identifier.
First You Have To Create New HashMap To Maintain The Child CheckBoxState in ExpandablelistView
Declare HashMap In Adapter As Like-
private HashMap mChildCheckStates;// New HashMap Created
Following Code Past In Your Adapter
cb.setOnCheckedChangeListener(null);
if (mChildCheckStates.containsKey(mGroupPosition)) {
boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
cb.setChecked(getChecked[mChildPosition]);
}else {
boolean getChecked[] = new boolean[getChildrenCount(mGroupPosition)];
mChildCheckStates.put(mGroupPosition, getChecked);
cb.setChecked(false);
}
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
getChecked[mChildPosition] = isChecked;
mChildCheckStates.put(mGroupPosition, getChecked);
//Toast.makeText(mContext,"group-"+mGroupPosition+"child-"+mChildPosition,Toast.LENGTH_SHORT).show();
// String value=mListDataChild[0];
Toast.makeText(mContext,"-"+mListDataChild,Toast.LENGTH_SHORT).show();
} else {
boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
getChecked[mChildPosition] = isChecked;
mChildCheckStates.put(mGroupPosition, getChecked);
Toast.makeText(mContext,"group-"+mGroupPosition+"child-"+mChildPosition,Toast.LENGTH_SHORT).show();
}
}
});
cb is checkbox.
I Hope This Logic I Help To AnyOne
Thanks
Related
I am developer a Apps which contain Various Name & Country List. I want to pass Employee Name & Country name to another activity on click on Child Item of Expandable ListView.
How to set On Click Listener Method on my Activity?
package nasir.main.activity;
import java.util.ArrayList;
import nasir.adapter.EntryItem;
import nasir.adapter.MyListAdapter;
import nasir.adapter.SectionItem;
import nasir.bd.poem.R;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.SearchView;
public class Employee_List extends Activity implements SearchView.OnQueryTextListener, SearchView.OnCloseListener {
Button Collapse;
Button Expand;
private SearchView search;
private MyListAdapter listAdapter;
private ExpandableListView myList;
private ArrayList<SectionItem> section = new ArrayList<SectionItem>();
ArrayList<EntryItem> items = new ArrayList<EntryItem>();
ExpandableListView expandableList = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.poem_list);
expandableList = (ExpandableListView) findViewById(R.id.expandableList);
Expand = (Button) findViewById(R.id.Expand);
Collapse = (Button) findViewById(R.id.Collapse);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
search = (SearchView) findViewById(R.id.search);
search.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
search.setIconifiedByDefault(false);
search.setOnQueryTextListener(this);
search.setOnCloseListener(this);
Collapse.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int count = listAdapter.getGroupCount();
for (int i = 0; i < count; i++){
myList.collapseGroup(i);
}
Collapse.setVisibility(View.GONE);
Expand.setVisibility(View.VISIBLE);
}
});
Expand.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int count = listAdapter.getGroupCount();
for (int i = 0; i < count; i++){
myList.expandGroup(i);
}
Expand.setVisibility(View.GONE);
Collapse.setVisibility(View.VISIBLE);
}
});
// display the list
displayList();
// expand all Groups
// expandAll();
collapseAll();
}
// method to expand all groups
private void expandAll() {
int count = listAdapter.getGroupCount();
for (int i = 0; i < count; i++) {
myList.expandGroup(i);
}
}
//method to Collapse all groups
private void collapseAll() {
int count = listAdapter.getGroupCount();
for (int i = 0; i < count; i++){
myList.collapseGroup(i);
}
}
// method to expand all groups
private void displayList() {
// display the list
load_Part_1_Data();
// get reference to the ExpandableListView
myList = (ExpandableListView) findViewById(R.id.expandableList);
// create the adapter by passing your ArrayList data
listAdapter = new MyListAdapter(Poem_List.this, section);
// attach the adapter to the list
myList.setAdapter(listAdapter);
myList.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView arg0, View arg1, int arg2,
int arg3, long arg4) {
// TODO Auto-generated method stub
Intent intent = new Intent(Poem_List.this, Details_Information.class);
startActivity(intent);
return false;
}
});
}
private void load_Part_1_Data() {
items = new ArrayList<EntryItem>();
section.add(new SectionItem(R.drawable.ic_launcher, "", items));
items.add(new EntryItem(R.drawable.ic_launcher, "Margerate Milan", "Computer Operator", getString(R.string.app_name)));
items.add(new EntryItem(R.drawable.ic_launcher, "Abraham Jhon", "Salse Man", getString(R.string.app_name)));
items = new ArrayList<EntryItem>();
section.add(new SectionItem(R.drawable.blank_image, "", items));
items.add(new EntryItem(R.drawable.ic_launcher, "England", "Europe", getString(R.string.app_name)));
items.add(new EntryItem(R.drawable.ic_launcher, "Japan", "Asia", getString(R.string.app_name)));
}
#Override
public boolean onClose() {
listAdapter.filterData("");
expandAll();
return true;
}
#Override
public boolean onQueryTextChange(String query) {
listAdapter.filterData(query);
expandAll();
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
listAdapter.filterData(query);
expandAll();
return false;
}
}
MyListAdapter.Class
package nasir.adapter;
import java.util.ArrayList;
import nasir.bd.poem.R;
import nasir.main.activity.Details_Information;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyListAdapter extends BaseExpandableListAdapter {
private Context context;
private ArrayList<SectionItem> continentList;
private ArrayList<SectionItem> originalList;
public MyListAdapter(Context context, ArrayList<SectionItem> continentList) {
this.context = context;
this.continentList = new ArrayList<SectionItem>();
this.continentList.addAll(continentList);
this.originalList = new ArrayList<SectionItem>();
this.originalList.addAll(continentList);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
ArrayList<EntryItem> countryList = continentList.get(groupPosition).getSectionList();
return countryList.get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View view, ViewGroup parent) {
final EntryItem country = (EntryItem) getChild(groupPosition, childPosition);
if (view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.child_row, null);
}
ImageView Rank = (ImageView) view.findViewById(R.id.Rank);
TextView Poem = (TextView) view.findViewById(R.id.Poem);
TextView Poetry = (TextView) view.findViewById(R.id.Poetry);
Rank.setImageResource(country.getRank());
Poem.setText(country.getPoem().trim());
Poetry.setText(country.getPoetry().trim());
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, Details_Information.class);
Bundle bundle=new Bundle();
intent.putExtras(bundle);
intent.putExtra("header", country.getDetails_Doc());
context.startActivity(intent);
}
});
return view;
}
#Override
public int getChildrenCount(int groupPosition) {
ArrayList<EntryItem> countryList = continentList.get(groupPosition).getSectionList();
return countryList.size();
}
#Override
public Object getGroup(int groupPosition) {
return continentList.get(groupPosition);
}
#Override
public int getGroupCount() {
return continentList.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isLastChild, View view, ViewGroup parent) {
SectionItem continent = (SectionItem) getGroup(groupPosition);
if (view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.group_row, null);
}
TextView heading = (TextView) view.findViewById(R.id.heading);
heading.setText(continent.getName().trim());
ImageView Group_icon = (ImageView) view.findViewById(R.id.Group_Icon);
Group_icon.setImageResource(continent.getIcon());
return view;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public void filterData(String query) {
query = query.toLowerCase();
Log.v("MyListAdapter", String.valueOf(continentList.size()));
continentList.clear();
if (query.isEmpty()) {
continentList.addAll(originalList);
} else {
for (SectionItem continent : originalList) {
ArrayList<EntryItem> countryList = continent.getSectionList();
ArrayList<EntryItem> newList = new ArrayList<EntryItem>();
for (EntryItem country : countryList) {
if (country.getPoem().toLowerCase().contains(query) || country.getPoetry().toLowerCase().contains(query) ) {
newList.add(country);
}
}
if (newList.size() > 0) {
SectionItem nContinent = new SectionItem(continent.getIcon(), continent.getName(), newList);
continentList.add(nContinent);
}
}
}
Log.v("MyListAdapter", String.valueOf(continentList.size()));
notifyDataSetChanged();
}
}
In the Employee_List activity , you can access the data through index of child and group obtaining from ChildClickListener
myList.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView arg0, View arg1, int arg2,
int arg3, long arg4) {
// TODO Auto-generated method stub
//Here You can access the child data by
final EntryItem country = (EntryItem) listAdapter .getChild(arg2, arg3);
//From here you can pass the data through Intent
...
return false;
}
});
I have a ExpandableListActivity that has groups and children. the chidren have a checkbox.
I've overridden setOnGroupExpandListener for when the user tap the group.
How can i check/uncheck the checkbox for each child for a particular group?
I've tried getting the adapter and calling getChild using the groupPosition but i'm lost in how do do this.
thanks in advance
import android.app.ExpandableListActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.Toast;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
public class ExpList extends ExpandableListActivity
{
String arrGroupelements[];
String arrChildelements[][];
private static final String TAG = ExpList.class.getSimpleName();
DisplayMetrics metrics;
int width;
ExpandableListView expList;
RROnCallApplication appObj;
Cursor companies;
Button mainMenu;
ExpAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
appObj = (RROnCallApplication) getApplication();
mainMenu = (Button)findViewById(R.id.buttonmainmenu);
mainMenu.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(ExpList.this, MenuActivity2.class);
startActivity(i);
}
});
try{
companies = appObj.dbModel.queryAllFromCompanyBranch();
arrGroupelements = new String[companies.getCount() ];
Log.e(TAG, "companies count = " + companies.getCount());
arrChildelements = new String[arrGroupelements.length][20];
if(companies != null && companies.getCount() > 0){
if(companies.moveToFirst()){
int i = 0;
do{
arrGroupelements[i] = companies.getString(companies.getColumnIndex(DBModel.C_COMPANYBRANCH_NAME));
Log.e(TAG, "arrGroupelements[" + i +"] = " + arrGroupelements[i]);
int compID = appObj.dbModel.getCompanyidFromName(arrGroupelements[i]);
Log.e(TAG, "compID = " + compID);
String[] branchesArr = appObj.dbModel.getBranchNamesfromCompanyId(compID);
Log.e(TAG, "branchesArr length = " + branchesArr.length);
for(int h = 0; h < branchesArr.length; h++){
arrChildelements[i][h] = branchesArr[h];
}
i++;
}while(companies.moveToNext());
Log.e(TAG, "arrGroupelements size = " + arrGroupelements.length);
}//end of moveToFirst
}
}catch(Exception e){
Toast.makeText(this, "There was a problem downloading companies and branches", Toast.LENGTH_LONG).show();
Log.e(TAG, "********Exception = " + e.toString());
}finally{
companies.close();
}
expList = getExpandableListView();
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.widthPixels;
//this code for adjusting the group indicator into right side of the view
expList.setIndicatorBounds(width - GetDipsFromPixel(50), width - GetDipsFromPixel(10));
expList.setAdapter(new ExpAdapter(this));
expList.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Log.e("onGroupExpand", "OK");
}
});
expList.setOnGroupCollapseListener(new OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Log.e("onGroupCollapse", "OK");
}
});
expList.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Log.e("OnChildClickListener", "OK Group = " + groupPosition
+ " child = " + childPosition);
TextView tvBranchName = (TextView) v.findViewById(R.id.tvPlayerName);
String branchName = tvBranchName.getText().toString();
Log.e(TAG, "branch name = " + branchName);
int branchID = appObj.dbModel.getBranchIdFromName(branchName);
Log.e(TAG, "branch ID = " + branchID);
final CheckBox cb = ((CheckBox)v.findViewById(R.id.checkbox));
if(cb.isChecked() == true){
Log.e(TAG, "checkBox is true but setting it to false now" );
cb.setChecked(false);
appObj.dbModel.updateBranchSelectedStatus(String.valueOf(branchID), "N");
Log.e(TAG, "just called updateBranchSelectedStatus with values " + String.valueOf(branchID) + " " + "N");
Log.e(TAG, "Branhes selected are " + appObj.dbModel.getBranchList());
}else{
Log.e(TAG, "checkBox is false but setting it to true");
cb.setChecked(true);
appObj.dbModel.updateBranchSelectedStatus(String.valueOf(branchID), "Y");
Log.e(TAG, "just called updateBranchSelectedStatus with values " + String.valueOf(branchID) + " " + "Y");
Log.e(TAG, "Branhes selected are " + appObj.dbModel.getBranchList());
}
return false;
}
});
}//end of onCreate
#Override
public void onBackPressed() {
super.onBackPressed();
Intent i = new Intent(this, OnCallMenuActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
public int GetDipsFromPixel(float pixels)
{
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 0.5f);
}
public class ExpAdapter extends BaseExpandableListAdapter {
private Context myContext;
public ExpAdapter(Context context) {
myContext = context;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.child_row, null);
}
TextView tvPlayerName = (TextView) convertView.findViewById(R.id.tvPlayerName);
tvPlayerName.setText(arrChildelements[groupPosition][childPosition]);
CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkbox);
int branchID = appObj.dbModel.getBranchIdFromName(arrChildelements[groupPosition][childPosition]);
Log.e(TAG, "inside getchildView and branchID = " + branchID);
boolean isBranchSelected = appObj.dbModel.isBranchSelected(String.valueOf(branchID));
Log.e(TAG, "isBranchSelected = " + isBranchSelected);
if(isBranchSelected == true){
cb.setChecked(true);
Log.e(TAG, "inside getchildView and cb.setChecked(true)");
}else{
cb.setChecked(false);
Log.e(TAG, "inside getchildView and cb.setChecked(false)");
}
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
//return arrChildelements[groupPosition].length;
int count = 0;
for (int i = 0; i < arrChildelements[groupPosition].length; i++)
count += arrChildelements[groupPosition][i] != null ? 1 : 0;
return count;
}
#Override
public Object getGroup(int groupPosition) {
return null;
}
#Override
public int getGroupCount() {
return arrGroupelements.length;
}
#Override
public long getGroupId(int groupPosition) {
return 0;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.group_row, null);
}
TextView tvGroupName = (TextView) convertView.findViewById(R.id.tvGroupName);
tvGroupName.setText(arrGroupelements[groupPosition]);
ExpandableListView mExpandableListView = (ExpandableListView) parent;
mExpandableListView.expandGroup(groupPosition);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
}
try creating an array of arrays of booleans called checked. then in getChildView check if that spot in the array is true, if so so the checkbox to checked.
then when you expand a parent loop through every element in that two dimential array setting them all to true and then calling notifyDataSetChanged
boolean [][] checked;
then in on expand
for(int i =0; i < checked[groupPosition].size; i++)
{
checked[groupPosition][i] = true;
}
notifyDataSetChanged();
in getChildView you should also but this
cb.setChecked(checked[groupPosition][childPosition]);
a sim thing can be done to uncheck them by setting it to false. just remember to update this array when a user checks or unchecks a button so when the list views are recycled you dont get randomly checked boxes.
Do not know why my volley request does not show any thing. It is not give me the failure instance but success listner does not call if I am using the ExpandableListView with BaseExpandableListAdapter.
See my Fragment class code: ShopCategoryFragment.java.
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import com.android.volley.Request.Method;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.Volley;
import com.examples.testone.domain.CategorySection;
import com.examples.testone.domain.ShopCategory;
import com.examples.testone.domain.ShopCategoryParent;
import com.examples.testone.domain.ShopCategorySection;
import com.examples.testone.domain.response.ShopCategorySectionsRestResponse;
import com.examples.testone.network.volley.GsonRequest;
public class ShopCategoryFragment extends Fragment {
// private ShopCategorySectionListAdapter shopCategorySectionListAdapter;
private RequestQueue requestQueue;
private boolean requestRunning = false;
private String volleyRequestMode = "in";
final String _appLogTag = " - ShopCategoryFragment - ";
private List<ShopCategorySectionVO> shopCategorySectionVOs;
Map<ShopCategorySectionVO, List<ShopCategory>> myMapCollection;
private ExpandableListView expListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setRetainInstance(true);
Log.d(_appLogTag, "Inside onCreate");
//this.requestQueue = SmartShopVolleySettings.getRequestQueue();
this.requestQueue = Volley.newRequestQueue(getActivity());
startRequest();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(_appLogTag, "Inside onCreateView");
View viewHierarchy =
inflater.inflate(R.layout.fragment_explist, container, false);
// List View Settings
expListView =
(ExpandableListView) viewHierarchy.findViewById(R.id.laptop_list);
// getActivity(), this.shopCategorySectionVOs, this.collection );
expListView.setAdapter
(new ShopCategoryExpandibleListAdapter(getActivity(),
shopCategorySectionVOs, myMapCollection));
return viewHierarchy;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d(_appLogTag, "Inside onViewCreated");
}
#Override
public void onDestroy() {
super.onResume();
Log.d(_appLogTag, "Inside onDestroy");
//this.requestQueue.cancelAll(this);
//this.requestRunning = false;
// cancelRequests();//Json shop lists
}
#Override
public void onPause() {
super.onPause();
Log.d(_appLogTag, "Inside onPause");
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// inflater.inflate(R.menu.simplemap_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
/*
* switch (item.getItemId()) {
*
* case R.id.simplemap_menu_info:
* SimpleDialogFragment.createBuilder(this.getActivity(),
* this.getActivity().getSupportFragmentManager())
* .setMessage(Html.fromHtml
* (getString(R.string.simplemap_info_details)))
* .setTitle(R.string.simplemap_info_title) .show(); return true; }
*/
return super.onOptionsItemSelected(item);
}
private void startRequest() {
Log.d(_appLogTag,"Inside on Start Request for getting the Shop Categories ");
if ( !requestRunning ) {
ShopCategoryFragment.this.requestRunning = true ;
String url = getString(R.string.shops_category_get_url, this.volleyRequestMode);
Log.d(_appLogTag, "Url for json is:" + url);
GsonRequest<ShopCategorySectionsRestResponse> jsonObjectRequest =
new GsonRequest<ShopCategorySectionsRestResponse>(Method.GET,
url, ShopCategorySectionsRestResponse.class,
null,
getShopsCategoriesRequestSuccessListener(),
getShopsCategoriesRequestErrorListener());
jsonObjectRequest.setShouldCache(false);
//Log.i(_appLogTag, " volley request Finished: "+
jsonObjectRequest.getBodyContentType() + " More: " + jsonObjectRequest.toString());
this.requestQueue.add(jsonObjectRequest);
} else if (BuildConfig.DEBUG) {
Log.i(_appLogTag, " volley request is already running");
}
/*myMapCollection = new LinkedHashMap<ShopCategorySectionVO,
List<ShopCategory>>(); // My Map
shopCategorySectionVOs = new ArrayList<ShopCategorySectionVO>(); // My Section Headers
List<ShopCategory> shopCategories = new ArrayList<ShopCategory>();
ShopCategorySectionVO shopCategorySectionVO1 =
new ShopCategorySectionVO("Dog", "icon", null);
shopCategorySectionVOs.add(shopCategorySectionVO1);
ShopCategory sc1 = new ShopCategory();
Title sc1t1 = new Title();
sc1t1.setEn("Tommy");
sc1.setTitle(sc1t1);
Description sc1d1 = new Description();
sc1d1.setEn("My Kuta Tommy");
sc1.setDescr(sc1d1);
shopCategories.add(sc1);
ShopCategory sc2 = new ShopCategory();
Title sc1t2 = new Title();
sc1t2.setEn("Boomer");
sc2.setTitle(sc1t2);
Description sc1d2 = new Description();
sc1d2.setEn("My Kuta Boomer");
sc2.setDescr(sc1d2);
shopCategories.add(sc2);
myMapCollection.put(shopCategorySectionVO1, shopCategories);*/
}
private Response.Listener<ShopCategorySectionsRestResponse>
getShopsCategoriesRequestSuccessListener() {
return new Response.Listener<ShopCategorySectionsRestResponse>() {
#Override
public void onResponse(ShopCategorySectionsRestResponse response) {
myMapCollection = new LinkedHashMap<ShopCategorySectionVO, List<ShopCategory>>();
shopCategorySectionVOs = new ArrayList<ShopCategorySectionVO>();
List<ShopCategory> shopCategories = new ArrayList<ShopCategory>();
Log.d(_appLogTag,"Ready for going inside");
for (CategorySection categorySection :response.getShop_category_sections()) {
Log.d(_appLogTag,"Inside Outer For");
ShopCategorySection catSection = categorySection.getShopCategorySection();
ShopCategorySectionVO shopCategorySectionVO =
new ShopCategorySectionVO
(catSection.getTitle(),catSection.getIcon(),
catSection.getBackcolor());
shopCategorySectionVOs.add(shopCategorySectionVO);
if (catSection.getShop_categories() != null &&
catSection.getShop_categories().size() > 0) {
Log.d(_appLogTag,"Inside Inner If");
for (ShopCategoryParent shopCategoryParent : catSection.getShop_categories()) {
Log.d(_appLogTag,"Inside Inner For");
ShopCategory shopCategory = shopCategoryParent.getShopCategory();
shopCategories.add(shopCategory);
}// End of child For
}// End of IF
myMapCollection.put(shopCategorySectionVO, shopCategories); // Filling of Map
}
// End of Outer For
requestRunning = false;
}
};
}
private Response.ErrorListener getShopsCategoriesRequestErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(_appLogTag,"Inside on create Shops Request Error Listener ");
requestRunning = false;
}
};
}
}
and my BaseExpandableListAdapter.
public class ShopCategoryExpandibleListAdapter extends BaseExpandableListAdapter {
final String _appLogTag = " - ShopCategoryExpandibleListAdapter - ";
// 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 Map<ShopCategorySectionVO, List<ShopCategory>> mListDataChild;
// ArrayList that is what each key in the above
// hashmap points to
private List<ShopCategorySectionVO> mCategorySectionVOs;
// Hashmap for keeping track of our checkbox check states
private Map<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;
//private String childText2;
/* Here's the constructor we'll use to pass in our calling
* activity's context, group items, and child items
*/
public ShopCategoryExpandibleListAdapter(Context context,
List<ShopCategorySectionVO> listDataGroup,
Map<ShopCategorySectionVO, List<ShopCategory>> listDataChild) {
Log.d(_appLogTag, "Inside Constructor");
mContext = context;
mCategorySectionVOs = listDataGroup;
mListDataChild = listDataChild;
// Initialize our hashmap containing our check states here
mChildCheckStates = new HashMap<Integer, boolean[]>();
}
#Override
public ShopCategory getChild(int groupPosition, int childPosition) {
Log.d(_appLogTag, "Inside getChild");
List<ShopCategory>
listOfChilds = mListDataChild.get(mCategorySectionVOs.get(groupPosition));
Log.d(_appLogTag, "So total number of childs in Group number "
+groupPosition+" are "+listOfChilds.size());
//return mListDataChild.get(mCategorySectionVOs.get(groupPosition)).get(childPosition);
return listOfChilds.get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
Log.d(_appLogTag, "Inside getChild ID");
return childPosition;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
Log.d(_appLogTag, "Inside getChild View");
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();
ShopCategory shopCategory = getChild(mGroupPosition, mChildPosition);
childText = shopCategory.getTitle().getEn();
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.laptop_child);
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);
//childViewHolder.mChildText2.setText(childText2);
/*
* 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 int getChildrenCount(int groupPosition) {
Log.d(_appLogTag, "Inside getChildrenCount");
//ShopCategory childList = mListDataChild.get(mCategorySectionVOs.get(groupPosition));
return mListDataChild.get(mCategorySectionVOs.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
Log.d(_appLogTag, "Inside getGroup");
return mCategorySectionVOs.get(groupPosition);
}
#Override
public int getGroupCount() {
Log.d(_appLogTag, "Inside getGroupCount");
return mCategorySectionVOs.size();
}
#Override
public long getGroupId(int groupPosition) {
Log.d(_appLogTag, "Inside getGroupId");
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).getGroupText();
Log.d(_appLogTag, "Inside getGroupView");
groupText = ((ShopCategorySectionVO)getGroup(groupPosition)).getTitle();
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);
groupViewHolder.mGroupText = (TextView) convertView.findViewById(R.id.laptop_head);
convertView.setTag(groupViewHolder);
} else {
groupViewHolder = (GroupViewHolder) convertView.getTag();
}
groupViewHolder.mGroupText.setText(groupText);
return convertView;
}
#Override
public boolean hasStableIds() {
Log.d(_appLogTag, "Inside hasStableIds");
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
Log.d(_appLogTag, "Inside isChildSelectable");
return false;
}
public final class GroupViewHolder {
TextView mGroupText;
}
public final class ChildViewHolder {
TextView mChildText;
TextView mChildText2;
CheckBox mCheckBox;
}
}
It does not make any sense If I just disable the adapter, volley request got get success and load data in my domain classes.
I think the mistake is that you want to fill ExpandableListView with data that are not loaded yet. In your onCreateView the myMapCollection is still empty. It is loaded after some time when the volley finishes its asyncTask. You need to refresh your UI when you get successful response that volley finished loading data.
Here's a pretty cookie cutter program that expands a list, and then when you click a child, it pops a message saying, "Child Clicked". But I want the expandable list to consists of recipes so that when clicked, it shows a popup window of the ingredients. I tried making it an arraylist of objects instead of strings, and having the objects contain the list of ingredients, but I got all tangled up when trying to display the ingredients.. Thanks in advance!
package com.poe.poeguide;
import java.util.ArrayList;
import com.actionbarsherlock.app.SherlockActivity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ExpandableListView;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
import com.actionbarsherlock.view.MenuItem;
import android.widget.ExpandableListView.OnChildClickListener;
public class Recipes extends SherlockActivity {
private ExpandableListView mExpandableList;
/** An array of strings to populate dropdown list */
String[] actions = new String[] {
"Recipes",
"Main Page",
"Attributes",
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipes);
/** Create an array adapter to populate dropdownlist */
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), R.layout.sherlock_spinner_item, actions);
/** Enabling dropdown list navigation for the action bar */
getSupportActionBar().setNavigationMode(com.actionbarsherlock.app.ActionBar.NAVIGATION_MODE_LIST);
/** Defining Navigation listener */
ActionBar.OnNavigationListener navigationListener = new OnNavigationListener() {
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
switch(itemPosition) {
case 0:
break;
case 1:
Intent a = new Intent(Recipes.this, MainActivity.class);
startActivity(a);
break;
}
return false;
}
};
getSupportActionBar().setListNavigationCallbacks(adapter, navigationListener);
adapter.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
mExpandableList = (ExpandableListView)findViewById(R.id.expandable_list);
ArrayList<Parent> arrayParents = new ArrayList<Parent>();
ArrayList<String> arrayChildren = new ArrayList<String>();
//======================================================================================
//here we set the parents and the children
//for each "i" create a new Parent object to set the title and the children
Parent parent = new Parent();
parent.setTitle("Pies");
arrayChildren.add("Apple Pie ");
arrayChildren.add("Blueberry Pie ");
parent.setArrayChildren(arrayChildren);
//in this array we add the Parent object. We will use the arrayParents at the setAdapter
arrayParents.add(parent);
//======================================================================================
//sets the adapter that provides data to the list.
mExpandableList.setAdapter(new MyCustomAdapter(Recipes.this,arrayParents));
mExpandableList.setOnChildClickListener(new OnChildClickListener()
{
#Override
public boolean onChildClick(ExpandableListView arg0, View arg1, int arg2, int arg3, long arg4)
{
Toast.makeText(getBaseContext(), "Child clicked", Toast.LENGTH_LONG).show();
return false;
}
});
}
#Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
getSupportMenuInflater().inflate(R.menu.activity_recipes, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
Before we begin, note that Recipes is a confusing name for an Activity. I would highly recommend changing the name to follow the standard convention of ending with the word "Activity" (e.g., RecipeActivity).
First you need to create a Recipe object so you can store the name and ingredients together. This object can be as simple or as complex as you need, but let's pretend it looks something like this:
import java.util.List;
public class Recipe {
private String name;
private List<String> ingredients;
private List<String> directions;
#Override
public String toString() {
// By default, the Adapter classes in Android will call toString() on
// your object to figure out how it should appear in lists. To make sure
// the list displays the recipe name, we return the recipe name here.
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getIngredients() {
return ingredients;
}
public void setIngredients(List<String> ingredients) {
this.ingredients = ingredients;
}
public List<String> getDirections() {
return directions;
}
public void setDirections(List<String> directions) {
this.directions = directions;
}
}
Notice that we override toString() for this object and return the recipe name. This way, when we ask our adapter class to display a list of Recipe objects, it knows what text should be shown for each item in the list.
When creating the data for your list, instead of:
ArrayList<String> arrayChildren = new ArrayList<String>();
Use:
List<Recipe> arrayChildren = new ArrayList<Recipe>();
(Note: You might need to modify the Parent class to take List<Recipe> or the generic List<?> for the children if that field is only accepting List<String> right now.)
Let's add one sample Recipe object:
Recipe salsa = new Recipe();
salsa.setName("Pineapple Salsa");
salsa.setIngredients(Arrays.asList("pineapple", "cilantro", "lime", "jalapeno"));
salsa.setDirections(Arrays.asList("Blend ingredients and enjoy"));
arrayChildren.add(salsa);
Now that your list is backed by Recipe objects instead of just strings, it's simply a matter of getting that object when a list item is clicked. Here's how you might do this:
mExpandableList.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// Get the selected recipe
Recipe recipe = (Recipe) parent.getExpandableListAdapter()
.getChild(groupPosition, childPosition);
// Build a string listing the ingredients
StringBuilder message = new StringBuilder("Ingredients:\n");
for (String ingredient : recipe.getIngredients())
message.append("\n").append(ingredient);
// Display a dialog listing the ingredients
new AlertDialog.Builder(MyGreatHelloWorldActivity.this)
.setTitle(recipe.getName()).setMessage(message)
.setPositiveButton("Yum!", null).show();
// Return true because we handled the click
return true;
}
});
Update: Here's how you can complete the task with a no-frills adapter for expandable lists.
I created a generic class called ExpandableListGroup (equivalent to your Parent class) to hold the children. The class is generic so it will work with any kind of objects, but we'll use it with Recipe objects.
import java.util.List;
public class ExpandableListGroup<T> {
private String name;
private List<T> children;
public ExpandableListGroup(String name, List<T> children) {
this.name = name;
this.children = children;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<T> getChildren() {
return children;
}
public void setChildren(List<T> children) {
this.children = children;
}
#Override
public String toString() {
return name;
}
}
Then I created the following generic ExpandableListArrayAdapter class:
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
public class ExpandableListArrayAdapter<T> extends BaseExpandableListAdapter {
private List<ExpandableListGroup<T>> groups;
private LayoutInflater inflater;
public ExpandableListArrayAdapter(Context context,
List<ExpandableListGroup<T>> groups) {
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.groups = groups;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
ExpandableListGroup<T> group = getGroup(groupPosition);
if (convertView == null) {
convertView = inflater.inflate(
android.R.layout.simple_expandable_list_item_1, parent,
false);
}
TextView text = (TextView) convertView;
text.setText(group.toString());
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
T item = getChild(groupPosition, childPosition);
if (convertView == null) {
convertView = inflater.inflate(
android.R.layout.simple_expandable_list_item_1, parent,
false);
}
TextView text = (TextView) convertView;
text.setText(item.toString());
return convertView;
}
#Override
public T getChild(int groupPosition, int childPosition) {
return groups.get(groupPosition).getChildren().get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public int getChildrenCount(int groupPosition) {
return groups.get(groupPosition).getChildren().size();
}
#Override
public ExpandableListGroup<T> getGroup(int groupPosition) {
return groups.get(groupPosition);
}
#Override
public int getGroupCount() {
return groups.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
Now, here's how you tie it all together:
// Create one list per group
List<Recipe> appetizers = new ArrayList<Recipe>(),
desserts = new ArrayList<Recipe>();
// TODO: Create Recipe objects and add to lists
List<ExpandableListGroup<Recipe>> groups = Arrays.asList(
new ExpandableListGroup<Recipe>("Appetizers", appetizers),
new ExpandableListGroup<Recipe>("Desserts", desserts));
mExpandableList.setAdapter(new ExpandableListArrayAdapter<Recipe>(this,
groups));
Im using an expandable list in my app,my question is when i scroll up and down in the list, views get changed, please let me know how to fix this
Thanks,
Sam.
below is the code
package com.test.android;
import java.util.ArrayList;
import java.util.Random;
import android.app.ExpandableListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.TextView;
/**
* Demonstrates expandable lists using a custom {#link ExpandableListAdapter}
* from {#link BaseExpandableListAdapter}.
*/
public class ExpandableList1 extends ExpandableListActivity {
MyExpandableListAdapter mAdapter;
ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up our adapter
mAdapter = new MyExpandableListAdapter(this);
setListAdapter(mAdapter);
}
/**
* A simple adapter which maintains an ArrayList of photo resource Ids.
* Each photo is displayed as an image. This adapter supports clearing the
* list of photos and adding a new photo.
*
*/
private Handler actionhandler = new Handler(){
/* (non-Javadoc)
* #see android.os.Handler#handleMessage(android.os.Message)
*/
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
mAdapter.notifyDataSetChanged();
progressDialog.dismiss();
}
};
public class MyExpandableListAdapter extends BaseExpandableListAdapter {
private ArrayList<String> groups = new ArrayList<String>();
private ArrayList<ArrayList<String>> children = new ArrayList<ArrayList<String>>();
private Context context;
public MyExpandableListAdapter(Context context) {
super();
this.context = context;
groups.add("People Names");
groups.add("Dog Names");
groups.add("Cat Names");
groups.add("Fish Names");
ArrayList<String> child1 = new ArrayList<String>();
child1.add("Arnold-1");
child1.add("Barry-2");
child1.add("Chuck-3");
child1.add("David-4");
child1.add("Arnold-5");
child1.add("Barry-6");
child1.add("Chuck-7");
child1.add("David-8");
child1.add("Arnold-9");
child1.add("Barry-10");
child1.add("Chuck-11");
child1.add("David-12");
child1.add("Arnold-13");
child1.add("Barry-14");
child1.add("Chuck-15");
child1.add("David-16");
children.add(child1);
ArrayList<String> child2 = new ArrayList<String>();
child2.add("Ace-17");
child2.add("Bandit-18");
child2.add("Cha-Cha-19");
child2.add("Deuce-20");
children.add(child2);
ArrayList<String> child3 = new ArrayList<String>();
child3.add("Fluffy-21");
child3.add("Snuggles-22");
child3.add("Fluffy-23");
child3.add("Snuggles-24");
child3.add("Fluffy-25");
child3.add("Snuggles-26");
child3.add("Fluffy-27");
child3.add("Snuggles-28");
child3.add("Fluffy-29");
child3.add("Snuggles-30");
child3.add("Fluffy-31");
child3.add("Snuggles-32");
child3.add("Fluffy-33");
child3.add("Snuggles-34");
children.add(child3);
ArrayList<String> child4 = new ArrayList<String>();
child4.add("Goldy-35");
child4.add("Bubbles-36");
child4.add("dummy-37");
child4.add("Goldy-38");
child4.add("Bubbles-39");
child4.add("dummy-40");
child4.add("Goldy-41");
child4.add("Bubbles-42");
child4.add("dummy-43");
child4.add("Goldy-44");
child4.add("Bubbles-45");
child4.add("dummy-46");
child4.add("Goldy-47");
child4.add("Bubbles-48");
child4.add("dummy-49");
children.add(child4);
}
public Object getChild(int groupPosition, int childPosition) {
return children.get(groupPosition).get(childPosition);
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public int getChildrenCount(int groupPosition) {
//if childern not avaibles.
return children.get(groupPosition).size();
}
private void getMoreData(int groupPosition, int childPosition){
Log.e("getMoreData", "calling groupPosition:"+groupPosition +"|childPosition:"+childPosition);
//remove the dummay record
children.get(groupPosition).remove(childPosition);
//adding a new group with data.
Random randomGenerator = new Random();
int count = randomGenerator.nextInt(100);
groups.add("More Data:" + count);
ArrayList<String> newData = new ArrayList<String>();
newData.add("Arnold"+count);
newData.add("Barry"+ count);
newData.add("Chuck"+ count);
newData.add("David"+ count);
children.add(newData);
//removing a record from exssitng group.
children.get(0).remove(0);
children.get(0).add("add to group0 shaggy");
//adding a record to group
children.get(1).add("shaggy add to group 2 shaggy");
//remove a groiup and corresponding childrens
groups.remove(2);
children.remove(2);
//adding a new record to last group.
children.get(groups.size()-1).add("new record");
//adding a dummy record to last group.
children.get(groups.size()-1).add("dummy");
}
public TextView getGenericView() {
// Layout parameters for the ExpandableListView
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 64);
TextView textView = new TextView(ExpandableList1.this);
textView.setLayoutParams(lp);
// Center the text vertically
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
// Set the text starting position
textView.setPadding(36, 0, 0, 0);
return textView;
}
public Button getGenericButton(final int groupPosition,final int childPosition) {
// Layout parameters for the ExpandableListView
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 64);
Button button = new Button(ExpandableList1.this);
button.setText("More");
button.setLayoutParams(lp);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
progressDialog = ProgressDialog.show(context, null, "Please Wait");
new Thread(){
/* (non-Javadoc)
* #see java.lang.Thread#run()
*/
#Override
public void run() {
getMoreData(groupPosition,childPosition);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
actionhandler.sendEmptyMessage(0);
}
}.start();
}
});
// Center the text vertically
button.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
// Set the text starting position
button.setPadding(36, 0, 0, 0);
return button;
}
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
Log.e("getChildView", groupPosition + "===" +groups.size());
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.chilldlayout_data, null);
// parent.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
}
if( groupPosition == groups.size()-1 && isLastChild){
//adding a button.
Button button = (Button)convertView.findViewById(R.id.more_button);
button.setVisibility(View.VISIBLE);
button.setText("More");
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
progressDialog = ProgressDialog.show(context, null, "Please Wait");
new Thread(){
/* (non-Javadoc)
* #see java.lang.Thread#run()
*/
#Override
public void run() {
getMoreData(groupPosition,childPosition);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
actionhandler.sendEmptyMessage(0);
}
}.start();
}
});
// Center the text vertically
button.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
// Set the text starting position
button.setPadding(36, 0, 0, 0);
return convertView;
}else{
Button button = (Button)convertView.findViewById(R.id.more_button);
button.setVisibility(View.GONE);
TextView textView = (TextView)convertView.findViewById(R.id.textView_data);
textView.setText(getChild(groupPosition, childPosition).toString());
return convertView;
}
}
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}
public int getGroupCount() {
return groups.size();
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
TextView textView = getGenericView();
textView.setText(getGroup(groupPosition).toString());
return textView;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public boolean hasStableIds() {
return true;
}
}
}