I have used an expandable list to accomplish the above design. However I have issues in doing the following.
The vacancy list should load depending on the value selected from the Account list.
Also when An account is selected by default the first name in the vacancy list should be selected and the name of the vacancy should replace test sarah
I have completed the above. How ever the vacancy name change only occurs when I click & expand the Vacancy list where as it should happen as I change the Account Name. Is there any way to do this ? I really need a solution on this. I have almost tried all references in the internet.
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> listOptionsHeader = new ArrayList<>();
private HashMap<String, List<String>> listDataChild = new HashMap<>();
private FontUtils fontUtils;
private TextView selectedChild;
private View selectedView;
private String value = null;
private AccountsViewModel accountsViewModel;
private VacancyViewModel vacancyViewModel;
private ExpandableListView expandableListView;
private View getSelectedView() {
return selectedView;
}
public void setSelectedView(View selectedView) {
this.selectedView = selectedView;
}
public ExpandableListAdapter(Context context) {
this.context = context;
this.fontUtils = new FontUtils(context);
this.accountsViewModel = new AccountsViewModel(context);
this.vacancyViewModel = new VacancyViewModel(context, Validators.selectedAccountId);
this.listOptionsHeader.add("Accounts");
this.listOptionsHeader.add("Vacancies");
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
super.registerDataSetObserver(observer);
}
#Override
public int getGroupCount() {
return this.listOptionsHeader.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return 1;
}
#Override
public Object getGroup(int groupPosition) {
return this.listOptionsHeader.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return this.listDataChild.get(this.listOptionsHeader.get(groupPosition)).get(childPosition);
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.expandable_header_layout, null);
}
TextView lblListHeader = (TextView) convertView.findViewById(R.id.lblListHeader);
fontUtils.changeFontOfTextViewtoOpenSansSemiBold(lblListHeader);
TextView selectedChild2 = (TextView) convertView.findViewById(R.id.selected_child);
fontUtils.changeFontOfTextViewtoOpenSansLight(selectedChild2);
if (value == null) {
if (groupPosition == 0) {
selectedChild2.setText(Validators.selectedAccountName);
} else if (groupPosition == 1) {
selectedChild2.setText(Validators.selectedVacancyName);
} else if (groupPosition == 2) {
selectedChild2.setText(Validators.selectedStatus.toString());
}
}
lblListHeader.setText(headerTitle);
convertView.setTag("HeaderView-" + headerTitle);
return convertView;
}
#Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
long groupId = getCombinedGroupId(getGroupId(groupPosition));
int buttonId = 0;
if (groupId != 0) {
String xxx = String.valueOf(getCombinedGroupId(getGroupId(groupPosition)));
buttonId = Integer.parseInt(xxx.substring(0, 5));
}
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.expandable_child_radio_layout, parent, false);
final RadioGroup radioGroup = (RadioGroup) convertView.findViewById(R.id.radio_group1);
radioGroup.removeAllViews();
radioGroup.setFocusable(false);
if (groupPosition == 0) {
List<Accounts> accountsList = accountsViewModel.getAccountsList();
List<String> accountNames = new ArrayList<>();
for (int x = 0; x < accountsList.size(); x++) {
accountNames.add(accountsList.get(x).getName());
}
listDataChild.put(listOptionsHeader.get(groupPosition), accountNames);
final RadioButton[] rb = new RadioButton[listDataChild.get(this.listOptionsHeader.get(groupPosition)).size()];
radioGroup.setOrientation(RadioGroup.VERTICAL);
for (int i = 0; i < listDataChild.get(this.listOptionsHeader.get(groupPosition)).size(); i++) {
rb[i] = new RadioButton(context);
final String childText = (String) getChild(groupPosition, i);
rb[i].setText(childText);
rb[i].setId(i + buttonId);
rb[i].setTag(accountsList.get(i).getId());
if (rb[i].getTag().toString().equalsIgnoreCase(Validators.selectedFilterAccountId)) {
rb[i].setChecked(true);
}
fontUtils.changeFontOfRadioButtontoOpenSansRegular(rb[i]);
rb[i].setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.letter_small));
radioGroup.addView(rb[i]);
final int finalI = i;
rb[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (getSelectedView() != null) {
selectedChild = (TextView) getSelectedView().findViewById(R.id.selected_child);
selectedChild.setText(rb[finalI].getText());
value = rb[finalI].getText().toString();
Validators.selectedRadioId = rb[finalI].getId();
Validators.selectedFilterAccountId = rb[finalI].getTag().toString();
Validators.selectedAccountName = rb[finalI].getText().toString();
vacancyViewModel = new VacancyViewModel(context, Validators.selectedFilterAccountId);
Validators.isAccountChanged = true;
getExpandableListView().collapseGroup(groupPosition);
}
}
});
}
} else if (groupPosition == 1) {
List<Vacancy> vacancyList = vacancyViewModel.getVacancyList();
List<String> vacancyNames = new ArrayList<>();
for (int x = 0; x < vacancyList.size(); x++) {
vacancyNames.add(vacancyList.get(x).getVacancyName());
}
listDataChild.put(listOptionsHeader.get(groupPosition), vacancyNames);
final RadioButton[] rb = new RadioButton[listDataChild.get(this.listOptionsHeader.get(groupPosition)).size()];
radioGroup.setOrientation(RadioGroup.VERTICAL);
for (int i = 0; i < listDataChild.get(this.listOptionsHeader.get(groupPosition)).size(); i++) {
rb[i] = new RadioButton(context);
final String childText = (String) getChild(groupPosition, i);
rb[i].setText(childText);
rb[i].setId(i + buttonId);
rb[i].setTag(vacancyList.get(i).getId());
if (Validators.isAccountChanged) {
rb[0].setChecked(true);
selectedChild = (TextView) getSelectedView().findViewById(R.id.selected_child);
Validators.selectedVacancyName = rb[0].getText().toString();
selectedChild.setText(rb[0].getText());
Validators.selectedFilterVacancyId = rb[0].getTag().toString();
} else {
if (rb[i].getTag().toString().equalsIgnoreCase(Validators.selectedFilterVacancyId)) {
rb[i].setChecked(true);
}
}
fontUtils.changeFontOfRadioButtontoOpenSansRegular(rb[i]);
rb[i].setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.letter_small));
radioGroup.addView(rb[i]);
final int finalI = i;
rb[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (getSelectedView() != null) {
selectedChild = (TextView) getSelectedView().findViewById(R.id.selected_child);
System.out.println(selectedChild.getId());
selectedChild.setText(rb[finalI].getText());
value = rb[finalI].getText().toString();
Validators.selectedRadioId = rb[finalI].getId();
Validators.selectedFilterVacancyId = rb[finalI].getTag().toString();
Validators.selectedVacancyName = rb[finalI].getText().toString();
Validators.isAccountChanged = false;
getExpandableListView().collapseGroup(groupPosition);
}
}
});
}
}
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public ExpandableListView getExpandableListView() {
return expandableListView;
}
public void setExpandableListView(ExpandableListView expandableListView) {
this.expandableListView = expandableListView;
}
}
Related
I have an expandable list View that has a check button, but the problem is I can only add one child item.
dataItem.setSubCategory(arSubCategory);
arCategory.add(dataItem);
dataItem = new DataItem();
dataItem.setCategoryName("Art");
arSubCategory = new ArrayList<>();
for(int j = 1; j < 6; j++) {
SubCategoryItem subCategoryItem = newSubCategoryItem();
subCategoryItem.setIsChecked(ConstantManager.CHECK_BOX_CHECKED_FALSE);
subCategoryItem.setSubCategoryName("Art: "+j);
arSubCategory.add(subCategoryItem);
}
I have tried to use but this has no check
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("do this and do that");
listDataHeader.add("do this and don't do that");
listDataHeader.add("don't do that but you can do this");
// Adding child data
List<String> 250 = new ArrayList<String>();
250.add("hmm what is this you doing");
// Header, Child data
listDataChild.put(listDataHeader.get(0), 250);
}
but the thing is that one is HashMap<String, List<String>>() and the other is ArrayList<ArrayList<HashMap<String, String>>> so it can work.
Is there a way I can make the first code add more item?
This is the adapter
import android.app.Activity;
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.ImageView;
import android.widget.TextView;
import com.apps.ayodkay.services.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MyCategoriesExpandableListAdapter extends
BaseExpandableListAdapter {
public static ArrayList<ArrayList<HashMap<String, String>>> childItems;
public static ArrayList<HashMap<String, String>> parentItems;
// private final ArrayList<HashMap<String, String>> childItems;
private LayoutInflater inflater;
private Activity activity;
private HashMap<String, String> child;
private int count = 0;
private boolean isFromMyCategoriesFragment;
public MyCategoriesExpandableListAdapter(Activity activity, ArrayList<HashMap<String, String>> parentItems,
ArrayList<ArrayList<HashMap<String, String>>> childItems,boolean isFromMyCategoriesFragment) {
MyCategoriesExpandableListAdapter.parentItems = parentItems;
MyCategoriesExpandableListAdapter.childItems = childItems;
this.activity = activity;
this.isFromMyCategoriesFragment = isFromMyCategoriesFragment;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getGroupCount() {
return parentItems.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return (childItems.get(groupPosition)).size();
}
#Override
public Object getGroup(int i) {
return null;
}
#Override
public Object getChild(int i, int i1) {
return null;
}
#Override
public long getGroupId(int i) {
return 0;
}
#Override
public long getChildId(int i, int i1) {
return 0;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(final int groupPosition, final boolean b, View convertView, ViewGroup viewGroup) {
final ViewHolderParent viewHolderParent;
if (convertView == null) {
if(isFromMyCategoriesFragment) {
convertView = inflater.inflate(R.layout.group_list_layout_my_categories, null);
}else {
convertView = inflater.inflate(R.layout.group_list_layout_choose_categories, null);
}
viewHolderParent = new ViewHolderParent();
viewHolderParent.tvMainCategoryName = convertView.findViewById(R.id.tvMainCategoryName);
viewHolderParent.cbMainCategory = convertView.findViewById(R.id.cbMainCategory);
viewHolderParent.ivCategory = convertView.findViewById(R.id.ivCategory);
convertView.setTag(viewHolderParent);
} else {
viewHolderParent = (ViewHolderParent) convertView.getTag();
}
if (parentItems.get(groupPosition).get(ConstantManager.Parameter.IS_CHECKED).equalsIgnoreCase(ConstantManager.CHECK_BOX_CHECKED_TRUE)) {
viewHolderParent.cbMainCategory.setChecked(true);
notifyDataSetChanged();
} else {
viewHolderParent.cbMainCategory.setChecked(false);
notifyDataSetChanged();
}
viewHolderParent.cbMainCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (viewHolderParent.cbMainCategory.isChecked()) {
parentItems.get(groupPosition).put(ConstantManager.Parameter.IS_CHECKED, ConstantManager.CHECK_BOX_CHECKED_TRUE);
for (int i = 0; i < childItems.get(groupPosition).size(); i++) {
childItems.get(groupPosition).get(i).put(ConstantManager.Parameter.IS_CHECKED, ConstantManager.CHECK_BOX_CHECKED_TRUE);
}
notifyDataSetChanged();
}
else {
parentItems.get(groupPosition).put(ConstantManager.Parameter.IS_CHECKED, ConstantManager.CHECK_BOX_CHECKED_FALSE);
for (int i = 0; i < childItems.get(groupPosition).size(); i++) {
childItems.get(groupPosition).get(i).put(ConstantManager.Parameter.IS_CHECKED, ConstantManager.CHECK_BOX_CHECKED_FALSE);
}
notifyDataSetChanged();
}
}
});
ConstantManager.childItems = childItems;
ConstantManager.parentItems = parentItems;
viewHolderParent.tvMainCategoryName.setText(parentItems.get(groupPosition).get(ConstantManager.Parameter.CATEGORY_NAME));
return convertView;
}
#Override
public View getChildView(final int groupPosition, final int childPosition, final boolean b, View convertView, ViewGroup viewGroup) {
final ViewHolderChild viewHolderChild;
child = childItems.get(groupPosition).get(childPosition);
if (convertView == null) {
convertView = inflater.inflate(R.layout.child_list_layout_choose_category, null);
viewHolderChild = new ViewHolderChild();
viewHolderChild.tvSubCategoryName = convertView.findViewById(R.id.tvSubCategoryName);
viewHolderChild.cbSubCategory = convertView.findViewById(R.id.cbSubCategory);
convertView.setTag(viewHolderChild);
} else {
viewHolderChild = (ViewHolderChild) convertView.getTag();
}
if (childItems.get(groupPosition).get(childPosition).get(ConstantManager.Parameter.IS_CHECKED).equalsIgnoreCase(ConstantManager.CHECK_BOX_CHECKED_TRUE)) {
viewHolderChild.cbSubCategory.setChecked(true);
notifyDataSetChanged();
} else {
viewHolderChild.cbSubCategory.setChecked(false);
notifyDataSetChanged();
}
viewHolderChild.tvSubCategoryName.setText(child.get(ConstantManager.Parameter.SUB_CATEGORY_NAME));
viewHolderChild.cbSubCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (viewHolderChild.cbSubCategory.isChecked()) {
count = 0;
childItems.get(groupPosition).get(childPosition).put(ConstantManager.Parameter.IS_CHECKED, ConstantManager.CHECK_BOX_CHECKED_TRUE);
notifyDataSetChanged();
} else {
count = 0;
childItems.get(groupPosition).get(childPosition).put(ConstantManager.Parameter.IS_CHECKED, ConstantManager.CHECK_BOX_CHECKED_FALSE);
notifyDataSetChanged();
}
for (int i = 0; i < childItems.get(groupPosition).size(); i++) {
if (childItems.get(groupPosition).get(i).get(ConstantManager.Parameter.IS_CHECKED).equalsIgnoreCase(ConstantManager.CHECK_BOX_CHECKED_TRUE)) {
count++;
}
}
if (count == childItems.get(groupPosition).size()) {
parentItems.get(groupPosition).put(ConstantManager.Parameter.IS_CHECKED, ConstantManager.CHECK_BOX_CHECKED_TRUE);
notifyDataSetChanged();
} else {
parentItems.get(groupPosition).put(ConstantManager.Parameter.IS_CHECKED, ConstantManager.CHECK_BOX_CHECKED_FALSE);
notifyDataSetChanged();
}
ConstantManager.childItems = childItems;
ConstantManager.parentItems = parentItems;
}
});
return convertView;
}
#Override
public boolean isChildSelectable(int i, int i1) {
return false;
}
#Override
public void onGroupCollapsed(int groupPosition) {
super.onGroupCollapsed(groupPosition);
}
#Override
public void onGroupExpanded(int groupPosition) {
super.onGroupExpanded(groupPosition);
}
private class ViewHolderParent {
TextView tvMainCategoryName;
CheckBox cbMainCategory;
ImageView ivCategory;
}
private class ViewHolderChild {
TextView tvSubCategoryName;
CheckBox cbSubCategory;
}
}
I think that you have custom classes similar to these:
DataItem:
public class DataItem {
private String categoryName;
private ArrayList<SubCategoryItem> subCategory;
private boolean isChecked;
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public ArrayList<SubCategoryItem> getSubCategory() {
return subCategory;
}
public void setSubCategory(ArrayList<SubCategoryItem> subCategory) {
this.subCategory = subCategory;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
public DataItem(){
categoryName = "Default Category";
subCategory = new ArrayList<>();
isChecked = false;
}
}
SubCategoryItem:
public class SubCategoryItem {
private String subCategoryName;
private boolean isChecked;
public String getSubCategoryName() {
return subCategoryName;
}
public void setSubCategoryName(String subCategoryName) {
this.subCategoryName = subCategoryName;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
public SubCategoryItem(){
subCategoryName = "Default Sub Category";
isChecked = false;
}
}
Then you can use those directly for the adapter, like below:
public class MyCategoriesExpandableListAdapter extends BaseExpandableListAdapter {
public ArrayList<DataItem> dataList;
private LayoutInflater inflater;
private Activity activity;
private int count;
private boolean isFromMyCategoriesFragment;
public MyCategoriesExpandableListAdapter(Activity activity, ArrayList<DataItem> dataList, boolean isFromMyCategoriesFragment) {
this.activity = activity;
this.dataList = dataList;
this.isFromMyCategoriesFragment = isFromMyCategoriesFragment;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getGroupCount() {
return dataList.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return dataList.get(groupPosition).getSubCategory().size();
}
#Override
public DataItem getGroup(int i) {
return dataList.get(i);
}
#Override
public SubCategoryItem getChild(int i, int i1) {
return dataList.get(i).getSubCategory().get(i1);
}
#Override
public long getGroupId(int i) {
return 0;
}
#Override
public long getChildId(int i, int i1) {
return 0;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(final int groupPosition, final boolean b, View convertView, ViewGroup viewGroup) {
final ViewHolderParent viewHolderParent;
if (convertView == null) {
if(isFromMyCategoriesFragment) {
convertView = inflater.inflate(R.layout.group_list_layout_my_categories, null);
}else {
convertView = inflater.inflate(R.layout.group_list_layout_choose_categories, null);
}
viewHolderParent = new ViewHolderParent();
viewHolderParent.tvMainCategoryName = convertView.findViewById(R.id.tvMainCategoryName);
viewHolderParent.cbMainCategory = convertView.findViewById(R.id.cbMainCategory);
viewHolderParent.ivCategory = convertView.findViewById(R.id.ivCategory);
convertView.setTag(viewHolderParent);
} else {
viewHolderParent = (ViewHolderParent) convertView.getTag();
}
viewHolderParent.cbMainCategory.setChecked(dataList.get(groupPosition).isChecked());
viewHolderParent.cbMainCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dataList.get(groupPosition).setChecked(viewHolderParent.cbMainCategory.isChecked());
for (int i = 0; i < dataList.get(groupPosition).getSubCategory().size(); i++) {
dataList.get(groupPosition).getSubCategory().get(i).setChecked(viewHolderParent.cbMainCategory.isChecked());
}
notifyDataSetChanged();
}
});
//ConstantManager.childItems = childItems;
//ConstantManager.parentItems = parentItems;
viewHolderParent.tvMainCategoryName.setText(dataList.get(groupPosition).getCategoryName());
return convertView;
}
#Override
public View getChildView(final int groupPosition, final int childPosition, final boolean b, View convertView, ViewGroup viewGroup) {
final ViewHolderChild viewHolderChild;
SubCategoryItem child = getChild(groupPosition, childPosition);
if (convertView == null) {
convertView = inflater.inflate(R.layout.child_list_layout_choose_category, null);
viewHolderChild = new ViewHolderChild();
viewHolderChild.tvSubCategoryName = convertView.findViewById(R.id.tvSubCategoryName);
viewHolderChild.cbSubCategory = convertView.findViewById(R.id.cbSubCategory);
convertView.setTag(viewHolderChild);
} else {
viewHolderChild = (ViewHolderChild) convertView.getTag();
}
viewHolderChild.cbSubCategory.setChecked(child.isChecked());
viewHolderChild.tvSubCategoryName.setText(child.getSubCategoryName());
viewHolderChild.cbSubCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getChild(groupPosition, childPosition).setChecked(viewHolderChild.cbSubCategory.isChecked());
count = 0;
for (int i = 0; i < getGroup(groupPosition).getSubCategory().size(); i++) {
if (getChild(groupPosition, i).isChecked()) {
count++;
}
}
getGroup(groupPosition).setChecked(count == getGroup(groupPosition).getSubCategory().size());
notifyDataSetChanged();
//ConstantManager.childItems = childItems;
//ConstantManager.parentItems = parentItems;
}
});
return convertView;
}
#Override
public boolean isChildSelectable(int i, int i1) {
return false;
}
#Override
public void onGroupCollapsed(int groupPosition) {
super.onGroupCollapsed(groupPosition);
}
#Override
public void onGroupExpanded(int groupPosition) {
super.onGroupExpanded(groupPosition);
}
private class ViewHolderParent {
TextView tvMainCategoryName;
CheckBox cbMainCategory;
ImageView ivCategory;
}
private class ViewHolderChild {
TextView tvSubCategoryName;
CheckBox cbSubCategory;
}
public ArrayList<SubCategoryItem> getCheckedList() {
ArrayList<SubCategoryItem> checkedItemList = new ArrayList<>();
for (DataItem dataItem : dataList) {
for (SubCategoryItem subCategoryItem : dataItem.getSubCategory()) {
if(subCategoryItem.isChecked()) checkedItemList.add(subCategoryItem);
}
}
return checkedItemList;
}
}
Create the data list like this:
String[] sampleGroups = {"Art", "Maths", "Language"};
ArrayList<DataItem> arCategory = new ArrayList<>();
for(int i = 0; i < sampleGroups.length; i++){
DataItem dataItem = new DataItem();
dataItem.setCategoryName(sampleGroups[i]);
ArrayList<SubCategoryItem> arSubCategory = new ArrayList<>();
for(int j = 1; j < 6; j++) {
SubCategoryItem subCategoryItem = new SubCategoryItem();
subCategoryItem.setSubCategoryName(dataItem.getCategoryName() + ": " + j);
arSubCategory.add(subCategoryItem);
}
dataItem.setSubCategory(arSubCategory);
arCategory.add(dataItem);
}
Hope that helps!
Hi I followed this Example and implemented expandablelist that keeps track of its childitems(check boxes). I just wanted to extend this feature. I want to keep track of checkbox ,spinner and edittext. I did the following changes but got array index error. Someone please help me to do the same.
Update: I made some progress. I preserved checkbox state. Still edittext and spinner pending.
public class ServiceListAdapter extends BaseExpandableListAdapter {
private Context mContext;
private HashMap<ServiceListModel, List<ServiceListModel>> mListDataChild;
private ArrayList<ServiceListModel> mListDataGroup;
// Hashmap for keeping track of our checkbox check states
private HashMap<Integer, List<ServiceListModel>> mChildCheckStates;
private ChildViewHolder childViewHolder;
private GroupViewHolder groupViewHolder;
private ServiceListModel groupService, childService;
#SuppressLint("UseSparseArrays")
public ServiceListAdapter(Context context, ArrayList<ServiceListModel> listDataGroup, HashMap<ServiceListModel, List<ServiceListModel>> listDataChild) {
mContext = context;
mListDataGroup = listDataGroup;
mListDataChild = listDataChild;
// Initialize our hashmap containing our check states here
mChildCheckStates = new HashMap<>();
}
public int getNumberOfCheckedItemsInGroup(int mGroupPosition) {
List<ServiceListModel> services= mChildCheckStates.get(mGroupPosition);
int count = 0;
if (services != null) {
for (int j = 0; j < services.size(); ++j) {
if (services.get(j).isSelected()) count++;
}
}
return count;
}
#Override
public int getGroupCount() {
return mListDataGroup.size();
}
#Override
public ServiceListModel 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) {
groupService = getGroup(groupPosition);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.nav_list_group_header, null);
groupViewHolder = new GroupViewHolder();
groupViewHolder.mGroupText = convertView.findViewById(R.id.lblListHeader);
convertView.setTag(groupViewHolder);
} else {
groupViewHolder = (GroupViewHolder) convertView.getTag();
}
groupViewHolder.mGroupText.setText(groupService.getMenuName());
final ImageView arrow = convertView.findViewById(R.id.arrow);
if (getGroup(groupPosition).isHasChildren()) {
arrow.setVisibility(View.VISIBLE);
} else arrow.setVisibility(View.GONE);
if (isExpanded) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
arrow.setImageDrawable(mContext.getDrawable(R.drawable.ic_arrow_up));
} else
arrow.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_arrow_up));
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
arrow.setImageDrawable(mContext.getDrawable(R.drawable.ic_arrow_down));
} else
arrow.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_arrow_down));
}
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return mListDataChild.get(mListDataGroup.get(groupPosition)).size();
}
#Override
public ServiceListModel getChild(int groupPosition, int childPosition) {
return mListDataChild.get(mListDataGroup.get(groupPosition)).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) {
ServiceListModel serviceListModel= getChild(groupPosition, childPosition);
final int mGroupPosition = groupPosition;
final int mChildPosition = childPosition;
childService = getChild(mGroupPosition, mChildPosition);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.services_child_item, null);
childViewHolder = new ChildViewHolder();
childViewHolder.mCheckBox = convertView.findViewById(R.id.serviceCheckBox);
childViewHolder.feeET = convertView.findViewById(R.id.feeET);
childViewHolder.daysSpinner = convertView.findViewById(R.id.daysSpinner);
convertView.setTag(R.layout.services_child_item, childViewHolder);
} else {
childViewHolder = (ChildViewHolder) convertView.getTag(R.layout.services_child_item);
}
childViewHolder.mCheckBox.setText(childService.getMenuName());
childViewHolder.mCheckBox.setOnCheckedChangeListener(null);
if (mChildCheckStates.containsKey(mGroupPosition)) {
List<ServiceListModel> services = mChildCheckStates.get(mGroupPosition);
childViewHolder.mCheckBox.setChecked(services.get(mChildPosition).isSelected());
childViewHolder.feeET.setText(services.get(mChildPosition).getFees());
} else {
List<ServiceListModel> serModel=mListDataChild.get(mListDataGroup.get(groupPosition));
mChildCheckStates.put(mGroupPosition, serModel);
childViewHolder.mCheckBox.setChecked(false);
childViewHolder.feeET.setText("");
}
final List<KeyPairBoolData> days = new ArrayList<>();
KeyPairBoolData h = new KeyPairBoolData();
h.setId(1);
h.setName("1-3 Days");
h.setSelected(false);
days.add(h);
h = new KeyPairBoolData();
h.setId(2);
h.setName("3-7 Days");
h.setSelected(false);
days.add(h);
h = new KeyPairBoolData();
h.setId(3);
h.setName("7-15 Days");
h.setSelected(false);
days.add(h);
h = new KeyPairBoolData();
h.setId(3);
h.setName("Above 15 Days");
h.setSelected(false);
days.add(h);
childViewHolder.daysSpinner.setItems(days, -1, new SpinnerListener() {
#Override
public void onItemsSelected(List<KeyPairBoolData> items) {
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected()) {
Log.i("blb07", i + " : " + items.get(i).getName() + " : " + items.get(i).isSelected());
}
}
}
});
childViewHolder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
List<ServiceListModel> serv= mChildCheckStates.get(mGroupPosition);
serv.get(mChildPosition).setSelected(isChecked);
mChildCheckStates.put(mGroupPosition, serv);
}
});
childViewHolder.feeET.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.i("blb07","before "+s);
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.i("blb07","On "+s);
}
#Override
public void afterTextChanged(Editable s) {
Log.i("blb07","after "+s);
List<ServiceListModel> serv= mChildCheckStates.get(mGroupPosition);
serv.get(mChildPosition).setFees(s.toString());
mChildCheckStates.put(mGroupPosition, serv);
}
});
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 {
SingleSpinner daysSpinner;
CheckBox mCheckBox;
EditText feeET;
}
}
The model class
public class ServiceListModel {
public boolean hasChildren, isGroup;
private String menuName, fees, days;
private int id;
private boolean selected;
public ServiceListModel(int id, String menuName, boolean isGroup, boolean hasChildren) {
this.menuName = menuName;
this.isGroup = isGroup;
this.hasChildren = hasChildren;
this.id = id;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public String getFees() {
return fees;
}
public void setFees(String fees) {
this.fees = fees;
}
public String getDays() {
return days;
}
public void setDays(String days) {
this.days = days;
}
}
I have not tested it but the problem could be in your loop using preincrement instead of postincrement:
public int getNumberOfCheckedItemsInGroup(int mGroupPosition) {
List<ServiceListModel> services= mChildCheckStates.get(mGroupPosition);
int count = 0;
if (services != null) {
for (int j = 0; j < services.size(); ++j) {
if (services.get(j).isSelected()) count++;
}
}
return count;
}
I guess for should be for (int j = 0; j < services.size(); j++)
I have a check list (Customized expandable list view) that I am populating through adapter. I want to retrieve an array from adapter to Activity on click of a text view in activity.
Activity is as follows, I want to retrieve data in onOptionsItemSelected function:
public class MyPreferencesActivity extends BaseActivity implements PreferencesContract.View, AdapterView.OnItemClickListener, ExpandableListView.OnGroupClickListener {
private PreferencesContract.Presenter mPresenterPreferences;
private Context context;
private ExpandableListView elvListView;
private ArrayList<CategoryModel> categories;
private ExpandableListAdapter ela;
private List<CategoryModel> mCategories;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_preferences);
this.context = this;
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
setupActionbar(toolbar, getString(R.string.preferneces), true, R.drawable.ab_home);
new PreferencesPresenter(this,
Injection.provideUseCaseHandler(),
Injection.provideGetCategories(getApplicationContext())
);
mPresenterPreferences.getCategories();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_save_my_preferences, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
//listener for home
switch (menuItem.getItemId()) {
case R.id.menu_create_event:
break;
}
return super.onOptionsItemSelected(menuItem);
}
private void populateList() {
categories = new ArrayList<>();
for (int i = 0; i < mCategories.size(); i ++){
categories.add(new CategoryModel(mCategories.get(i).getCategoryName(), mCategories.get(i).getCategoryId(), mCategories.get(i).getSubCategories()));
}
}
#Override
public void onItemClick(AdapterView<?> adapterView, android.view.View view, int i, long l) {
}
#Override
public boolean onGroupClick(ExpandableListView expandableListView, android.view.View view, int i, long l) {
return false;
}
#Override
public void setLoading(boolean isActive) {}
public void initViews(){
ela = new ExpandableListAdapter(this, categories);
elvListView = (ExpandableListView) findViewById(R.id.lv_preferences);
elvListView.setAdapter(ela);
elvListView.setOnItemClickListener(this);
elvListView.setOnGroupClickListener(this);
}
#Override
public void showGetPreferencesSuccess(List<CategoryModel> categories) {
setLoading(false);
mCategories = categories;
populateList();
initViews();
}
#Override
public void showGetPreferencesFail(int errorCode) {
}
#Override
public void setPresenter(PreferencesContract.Presenter presenter) {
mPresenterPreferences = Preconditions.checkNotNull(presenter);
}
}
Adapter is as follows:
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private ArrayList<String> item;
private ArrayList<Boolean> itemsChecked;
private ArrayList<ArrayList<Boolean>> childChecked;
private ArrayList<ArrayList<String>> childList;
public ExpandableListAdapter(Context c, ArrayList<CategoryModel> d) {
this.context = c;
this.item = new ArrayList<>();
for (int i = 0; i< d.size(); i++){
this.item.add(d.get(i).getCategoryName());
ArrayList<String> subCat = new ArrayList<>();
for (int j = 0 ; j < d.get(j).getSubCategories().size() ; j++){
subCat.add(d.get(j).getSubCategories().get(j).getSubCategoryName());
}
childList.add(subCat);
}
itemsChecked = new ArrayList<>();
childChecked = new ArrayList<ArrayList<Boolean>>();
for (int i = 0; i < this.item.size() ; i++) {
itemsChecked.add(false);
ArrayList <Boolean>temp = new ArrayList<>();
for (int j = 0 ; j < childList.get(i).size(); j ++){
temp.add(false);
}
childChecked.add(temp);
}
}
#Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, final ViewGroup parent) {
LayoutInflater infalInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.my_preferences_list_group, null);
TextView tvName = (TextView) convertView.findViewById(R.id.tvGroupName);
final CheckBox checkBox = (CheckBox)convertView.findViewById(R.id.checkbox);
if((getChildrenCount(groupPosition) == 0 && itemsChecked.get(groupPosition))|| (getChildrenCount(groupPosition) > 0 && !(childChecked.get(groupPosition).contains(false)))) {
checkBox.setChecked(true);
}
else {
checkBox.setChecked(false);
}
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CheckBox checkBox = (CheckBox)view;
RelativeLayout vwParentRow = (RelativeLayout)view.getParent();
TextView child = (TextView)vwParentRow.getChildAt(0);
final int position = item.indexOf(child.getText());
if (checkBox.isChecked()){
itemsChecked.set(position, true);
for (int i = 0 ; i < getChildrenCount(groupPosition); i++){
childChecked.get(groupPosition).set(i, true);
}
}
else {
itemsChecked.set(position, false);
for (int i = 0 ; i < getChildrenCount(groupPosition); i++){
childChecked.get(groupPosition).set(i, false);
}
}
ExpandableListAdapter.this.notifyDataSetChanged();
}
});
TextView tvCount = (TextView) convertView.findViewById(R.id.tv_item_count);
tvName.setText(item.get(groupPosition));
int childCount = getChildrenCount(groupPosition);
if (childCount > 0) {
tvCount.setText(getChildrenCount(groupPosition) + "items");
tvCount.setVisibility(View.VISIBLE);
}
if (isExpanded) {
}
else {
}
return convertView;
}
#Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
LayoutInflater infalInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.my_preferences_list_item, null);
TextView tvName = (TextView) convertView.findViewById(R.id.tv_item);
CheckBox checkBox = (CheckBox)convertView.findViewById(R.id.checkBox);
if (childChecked.get(groupPosition).get(childPosition))
checkBox.setChecked(true);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CheckBox checkBox = (CheckBox)view;
RelativeLayout vwParentRow = (RelativeLayout)view.getParent();
TextView child = (TextView)vwParentRow.getChildAt(0);
int position = -1;
for (int i = 0 ; i < childList.size(); i++){
if (childList.get(i).contains(child.getText())){
if(checkBox.isChecked()) {
childChecked.get(i).set(childList.get(i).indexOf(child.getText()) , true);
ExpandableListAdapter.this.notifyDataSetChanged();
}
else {
childChecked.get(i).set(childList.get(i).indexOf(child.getText()) , false);
ExpandableListAdapter.this.notifyDataSetChanged();
}
}
}
if (checkBox.isChecked()){
if (position >0 )
itemsChecked.set(position, true);
}
else if(position > 0) {
itemsChecked.set(position, false);
}
}
});
String s = childList.get(groupPosition).get(childPosition);
tvName.setText(s);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return childList.get(groupPosition).size();
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return childList.get(groupPosition).get(childPosition);
}
#Override
public int getGroupCount() {
return item.size();
}
#Override
public Object getGroup(int groupPosition) {
return item.get(groupPosition);
}
#Override
public long getGroupId(int groupPosition) {
return 0;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
I have an idea of sending data from Activity to Adapter.
Any help in doing it some other way?
I think it's as simple as creating a getter inside your adapter
public List<String> getItems() {
return this.item;
}
And inside onOptionsItemSelected in the activity
ela.getItems();
[Adapter class]
public class CustomExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<FilterList>> expandableListDetail;
private boolean checked;
private int lastClickedPosition;
private List<Boolean> setValueForSeletedFilter;
private String[] keysOfHashmap;
public CustomExpandableListAdapter(Context context, List<String> expandableListTitle,
HashMap<String, List<FilterList>> expandableListDetail, List<Boolean> setValueForSeletedFilter) {
this.context = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
this.setValueForSeletedFilter = setValueForSeletedFilter;
}
#Override
public Object getChild(int listPosition, int expandedListPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.get(expandedListPosition).getSearchFilterValue();
}
#Override
public long getChildId(int listPosition, int expandedListPosition) {
return expandedListPosition;
}
#Override
public View getChildView(final int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String expandedListText = (String) getChild(listPosition, expandedListPosition);
if (convertView == null) {
int i = listPosition;
int j = expandedListPosition;
LayoutInflater layoutInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_item, null);
TextView expandedListTextView = (TextView) convertView
.findViewById(R.id.expandedListItem);
expandedListTextView.setText(expandedListText);
String s = expandableListTitle.get(listPosition);
final ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_select);
if (setValueForSeletedFilter.get(expandedListPosition) == true) {
imageView.setVisibility(View.VISIBLE);
} else {
imageView.setVisibility(View.GONE);
}
}
return convertView;
}
private void toggleSelection(int i, View v) {
int j = i;
ImageView imageView = (ImageView) v.findViewById(R.id.iv_select);
imageView.setImageResource(R.drawable.ic_review);
}
#Override
public int getChildrenCount(int listPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.size();
}
#Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
#Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
#Override
public long getGroupId(int listPosition) {
return listPosition;
}
#Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String listTitle = (String) getGroup(listPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_group, null);
}
TextView listTitleTextView = (TextView) convertView
.findViewById(R.id.listTitle);
listTitleTextView.setTypeface(null, Typeface.BOLD);
listTitleTextView.setText(listTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return true;
}
public void setData(){
notifyDataSetChanged();
}
#Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
return true;
}
}
[setting values for adapter class and notifying adapter on changing values]
final HashMap> setValueForSeletedFilter = new HashMap<>();
String header = null;
final List booleanList = new ArrayList<>();
final HashMap> stringListHashMap = new HashMap<>();
final List expandableListTitle;
for (int i = 0; i < filtersInfos.size(); i++) {
stringListHashMap.put(filtersInfos.get(i).getFilterHeaderName(), filtersInfos.get(i).getFilterLists());
if (filtersInfos.get(i).getFilterHeaderName().equalsIgnoreCase("Distance")) {
header = filtersInfos.get(i).getFilterHeaderName();
for (int j = 0; j < filtersInfos.get(i).getFilterLists().size(); j++)
booleanList.add(false);
}
}
setValueForSeletedFilter.put(header, booleanList);
expandableListTitle = new ArrayList<String>(stringListHashMap.keySet());
final CustomExpandableListAdapter adapter = new CustomExpandableListAdapter(this, expandableListTitle, stringListHashMap, booleanList);
expandableListView.setAdapter(adapter);
filterDialog.show();
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Expanded.",
Toast.LENGTH_SHORT).show();
}
});
expandableListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Collapsed.",
Toast.LENGTH_SHORT).show();
}
});
final boolean[] checked = {false};
final int[] lastClickedPosition = {0};
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
if (expandableListTitle.get(groupPosition).equalsIgnoreCase("Distance")) {
booleanList.add(childPosition, true);
setValueForSeletedFilter.put(expandableListTitle.get(groupPosition), booleanList);
expandableListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
return false;
}
});
close.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
filterDialog.dismiss();
}
});
done.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
on the basis of header make list single or multi selection android.
getChildView() example for my case "Single selection"
#Override
public View getChildView(final int i, final int i1, boolean b, View view, ViewGroup viewGroup) {
View v = LayoutInflater.from(context).inflate(R.layout.expandablelv_child, null);
final CheckBox checkBox = v.findViewById(R.id.expandable_lv_child_cb);
RelativeLayout quantityContainer = v.findViewById(R.id.expandable_lv_child_quantity_cont);
final TextView textView = v.findViewById(R.id.expandable_lv_child_quantity_tv);
checkBox.setText(children.get(i).get(i1).getItemName());
double d=Double.parseDouble(children.get(i).get(i1).getMinQty());
int k=(int)d;
textView.setText(String.valueOf(k));
quantityContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
QuantityDialog dialog = new QuantityDialog(context, children.get(i).get(i1).getMinQty(),
children.get(i).get(i1).getMaxQty(), new DialogSelectable() {
#Override
public void onQuantitySelected(String quantity) {
if (group[i].parent == 1 && group[i].child == i1)
textView.setText(quantity);
ExpandableLvAdapter.quantity[i] = quantity;
}
});
dialog.show();
}
});
try {
// if (model.children.get(i).size() < children.get(i).size()) {
try {
model.children.get(i).add(checkBox);
} catch (Exception e) {
ArrayList<CheckBox> temp = new ArrayList<>();
temp.add(checkBox);
model.children.add(temp);
}
//}
} catch (Exception e) {
try {
model.children.get(i).add(checkBox);
} catch (Exception ex) {
ArrayList<CheckBox> temp = new ArrayList<>();
temp.add(checkBox);
model.children.add(temp);
}
}
if (group[i].parent == 1) {
model.children.get(i).get(group[i].child).setEnabled(true);
model.children.get(i).get(group[i].child).setChecked(true);
model.disable(i, children.get(i).get(group[i].child).getItemName());
} else {
model.enable(i);
}
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
group[i].parent = 1;
group[i].child = i1;
model.disable(i, children.get(i).get(i1).getItemName());
selected.add(children.get(i).get(i1));
quantity[i] = children.get(i).get(i1).getMaxQty();
} else {
group[i].parent = 0;
model.enable(i);
}
}
});
return v;
}
I have a dummy JSON data which has an ArrayList with size of 8. They must be populated in the expandableListView, but it shows only the first group. Because when I debug it, getGroupView always is invoked with groupPosition parameter as zero.
There are lots of examples about populating ExpandableListViews with ArrayLists and my code is almost the same with them. But I didn't understand why this happens.
Any help will be much appreciated
My ExpandableListViewApdater:
public class ElvProgramCourseListAdapter extends BaseExpandableListAdapter {
private Activity activity;
private ProgramOnly programOnly;
public ElvProgramCourseListAdapter(Activity activity, ProgramOnly programOnly) {
this.activity = activity;
this.programOnly = programOnly;
}
#Override
public int getGroupCount() {
return programOnly.getProgramSummary().getProgramSetList().size();
}
#Override
public int getChildrenCount(int groupPosition) {
NativeProgramSet item = programOnly.getProgramSummary().getProgramSetList().get(groupPosition);
if (item.getId() != null) {
return item.getCourseIdList().size();
} else {
return 0;
}
}
#Override
public Object getGroup(int groupPosition) {
return programOnly.getProgramSummary().getProgramSetList().get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
NativeProgramSet item = programOnly.getProgramSummary().getProgramSetList().get(groupPosition);
if (item.getId() != null) {
return item.getCourseIdList().get(childPosition);
} else {
return null;
}
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ImageView imgContentListThumbnail;
ImageView imgContentListRibbon;
ImageView imgTLIcon;
ImageView imgKilitIcon;
TextView txtContentListTitle;
TextView txtContentListDescription;
ImageView imgContentListDetail;
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.item_contentlist, parent, false);
imgContentListThumbnail = (ImageView) convertView.findViewById(R.id.imgContentListThumbnail);
imgContentListRibbon = (ImageView) convertView.findViewById(R.id.imgContentListRibbon);
imgTLIcon = (ImageView) convertView.findViewById(R.id.imgTLIcon);
imgKilitIcon = (ImageView) convertView.findViewById(R.id.imgKilitIcon);
txtContentListTitle = (TextView) convertView.findViewById(R.id.txtContentListTitle);
Fonts.setTypeface(Fonts.BOLD, txtContentListTitle, activity.getBaseContext());
txtContentListDescription = (TextView) convertView.findViewById(R.id.txtContentListDescription);
imgContentListDetail = (ImageView) convertView.findViewById(R.id.imgContentListDetail);
convertView.setTag(new ViewHolder(imgContentListThumbnail, imgContentListRibbon, imgTLIcon, imgKilitIcon, txtContentListTitle, txtContentListDescription, imgContentListDetail));
} else {
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
imgContentListThumbnail = viewHolder.imgContentListThumbnail;
imgContentListRibbon = viewHolder.imgContentListRibbon;
imgTLIcon = viewHolder.imgTLIcon;
imgKilitIcon = viewHolder.imgKilitIcon;
txtContentListTitle = viewHolder.txtContentListTitle;
txtContentListDescription = viewHolder.txtContentListDescription;
imgContentListDetail = viewHolder.imgContentListDetail;
}
NativeProgramSet nativeProgramSet = (NativeProgramSet) getGroup(groupPosition);
if(nativeProgramSet.getId() != null) {
convertView.setBackgroundColor(Color.parseColor("#e5e5e5"));
imgContentListThumbnail.setVisibility(View.GONE);
imgContentListRibbon.setVisibility(View.GONE);
imgTLIcon.setVisibility(View.GONE);
imgKilitIcon.setVisibility(View.GONE);
txtContentListDescription.setVisibility(View.GONE);
if(isExpanded) {
imgContentListDetail.setImageResource(R.drawable.accordion_close_icon);
} else {
imgContentListDetail.setImageResource(R.drawable.accordion_open_icon);
}
txtContentListTitle.setText(nativeProgramSet.getName());
} else {
convertView.setBackgroundColor(Color.WHITE);
imgContentListThumbnail.setVisibility(View.VISIBLE);
txtContentListDescription.setVisibility(View.VISIBLE);
imgContentListDetail.setImageResource(R.drawable.top_search_filter_button_icon);
Course course = null;
for(Course item : programOnly.getProgramSummary().getCourseList()) {
if(item.getId().equals(nativeProgramSet.getCourseIdList().get(0))) {
course = item;
break;
}
}
if(course != null) {
convertView = fillListItem(course, imgContentListThumbnail, imgContentListRibbon, imgTLIcon, imgKilitIcon, txtContentListTitle, txtContentListDescription, imgContentListDetail, convertView);
}
}
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ImageView imgContentListThumbnail;
ImageView imgContentListRibbon;
ImageView imgTLIcon;
ImageView imgKilitIcon;
TextView txtContentListTitle;
TextView txtContentListDescription;
ImageView imgContentListDetail;
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.item_contentlist, parent, false);
imgContentListThumbnail = (ImageView) convertView.findViewById(R.id.imgContentListThumbnail);
imgContentListRibbon = (ImageView) convertView.findViewById(R.id.imgContentListRibbon);
imgTLIcon = (ImageView) convertView.findViewById(R.id.imgTLIcon);
imgKilitIcon = (ImageView) convertView.findViewById(R.id.imgKilitIcon);
txtContentListTitle = (TextView) convertView.findViewById(R.id.txtContentListTitle);
Fonts.setTypeface(Fonts.BOLD, txtContentListTitle, activity.getBaseContext());
txtContentListDescription = (TextView) convertView.findViewById(R.id.txtContentListDescription);
imgContentListDetail = (ImageView) convertView.findViewById(R.id.imgContentListDetail);
convertView.setTag(new ViewHolder(imgContentListThumbnail, imgContentListRibbon, imgTLIcon, imgKilitIcon, txtContentListTitle, txtContentListDescription, imgContentListDetail));
} else {
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
imgContentListThumbnail = viewHolder.imgContentListThumbnail;
imgContentListRibbon = viewHolder.imgContentListRibbon;
imgTLIcon = viewHolder.imgTLIcon;
imgKilitIcon = viewHolder.imgKilitIcon;
txtContentListTitle = viewHolder.txtContentListTitle;
txtContentListDescription = viewHolder.txtContentListDescription;
imgContentListDetail = viewHolder.imgContentListDetail;
}
Long courseId = (Long) getChild(groupPosition, childPosition);
imgContentListThumbnail.setVisibility(View.VISIBLE);
txtContentListDescription.setVisibility(View.VISIBLE);
imgContentListDetail.setImageResource(R.drawable.top_search_filter_button_icon);
Course course = null;
for(Course item : programOnly.getProgramSummary().getCourseList()) {
if(item.getId().equals(courseId)) {
course = item;
break;
}
}
if(course != null) {
convertView = fillListItem(course, imgContentListThumbnail, imgContentListRibbon, imgTLIcon, imgKilitIcon, txtContentListTitle, txtContentListDescription, imgContentListDetail, convertView);
}
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
private static class ViewHolder {
public final ImageView imgContentListThumbnail;
public final ImageView imgContentListRibbon;
public final ImageView imgTLIcon;
public final ImageView imgKilitIcon;
public final TextView txtContentListTitle;
public final TextView txtContentListDescription;
public final ImageView imgContentListDetail;
public ViewHolder(ImageView imgContentListThumbnail, ImageView imgContentListRibbon, ImageView imgTLIcon, ImageView imgKilitIcon, TextView txtContentListTitle, TextView txtContentListDescription, ImageView imgContentListDetail) {
this.imgContentListThumbnail = imgContentListThumbnail;
this.imgContentListRibbon = imgContentListRibbon;
this.imgTLIcon = imgTLIcon;
this.imgKilitIcon = imgKilitIcon;
this.txtContentListTitle = txtContentListTitle;
this.txtContentListDescription = txtContentListDescription;
this.imgContentListDetail = imgContentListDetail;
}
}
private View fillListItem(final Course crs, ImageView imgContentListThumbnail, ImageView imgContentListRibbon, ImageView imgTLIcon, ImageView imgKilitIcon, TextView txtContentListTitle, TextView txtContentListDescription, ImageView imgContentListDetail, View convertView) {
//long stuff
}
}
EDIT
ProgramOnly.class
public class ProgramOnly implements Serializable {
/**
*
*/
private static final long serialVersionUID = 75459834905648086L;
private String HtmlContent;
private Course currentCourse;
private Program program;
private int videoCount;
private int quizCount;
private int eLearningCount;
private ArrayList<Page> orderedRelatedContent;
private String KALTURA_SESSION_KEY;
private String KALTURA_PREVIEW_SESSION_KEY;
private String videoId;
private boolean isPublicAccess;
private ArrayList<Document> contentDocuments;
private CourseStatusMap courseStatusMap;
private CertificateStatusMap certificateStatus;
private String programAttendeeId;
private String attendeeId;
private int pdfCount;
private int pptCount;
private int htmlCount;
private int audioCount;
private int interval;
private ProgramStatus contentStatus;
private String urlForSocialSharing;
private boolean isContentMustBePurchased;
public Program getProgramSummary() {
return program;
}
//getter setter stuff
I found the solution. Android is not as clever as I expected. My ExpandableListView is in a ScrollView and that makes its height always the same with one item. What a bug!
So I hack Android by measuring total height at just after setting adapter and onGroupExpand and onGroupCollapse
Setting Adapter:
ExpandableListView elvProgramCourseList = (ExpandableListView) findViewById(R.id.elvProgramCourseList);
ElvProgramCourseListAdapter adapter = new ElvProgramCourseListAdapter(this, programOnly);
elvProgramCourseList.setGroupIndicator(null);
elvProgramCourseList.setChildIndicator(null);
elvProgramCourseList.setAdapter(adapter);
setExpandableListViewHeightBasedOnChildren(elvProgramCourseList, null);
onGroupExpand:
elvProgramCourseList.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
ExpandableListView elvProgramCourseList = (ExpandableListView) findViewById(R.id.elvProgramCourseList);
collapseOtherGroups(elvProgramCourseList, groupPosition);
setExpandableListViewHeightBasedOnChildren(elvProgramCourseList, groupPosition);
}
});
onGroupCollapse:
elvProgramCourseList.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
ExpandableListView expandableListView = (ExpandableListView) findViewById(R.id.elvProgramCourseList);
ExpandableListAdapter expandableListAdapter = expandableListView.getExpandableListAdapter();
if (expandableListAdapter == null) {
return;
}
boolean areAllGroupsCollapsed = true;
for (int i = 0; i < expandableListAdapter.getGroupCount(); i++) {
if(expandableListView.isGroupExpanded(i)) {
areAllGroupsCollapsed = false;
break;
}
}
if(areAllGroupsCollapsed) {
setExpandableListViewHeightBasedOnChildren(expandableListView, null);
}
}
});
Measuring the total height:
private void setExpandableListViewHeightBasedOnChildren(ExpandableListView expandableListView, Integer expandedGroupPosition) {
ExpandableListAdapter expandableListAdapter = expandableListView.getExpandableListAdapter();
if (expandableListAdapter == null) {
return;
}
int totalHeight = 0;
int totalDividerHeight = 0;
for (int i = 0; i < expandableListAdapter.getGroupCount(); i++) {
View groupItem = expandableListAdapter.getGroupView(i, expandedGroupPosition != null, null, expandableListView);
totalHeight += Utils.convertDpToPixel(92.42f, this);
if(expandedGroupPosition != null && expandedGroupPosition.equals(i)) {
for(int j=0;j<expandableListAdapter.getChildrenCount(i);j++) {
View childItem = expandableListAdapter.getChildView(i, j, j+1==expandableListAdapter.getChildrenCount(i), null, expandableListView);
totalHeight += Utils.convertDpToPixel(92.42f, this);
}
totalDividerHeight += expandableListView.getDividerHeight() * (expandableListAdapter.getChildrenCount(i)-1);
}
}
totalDividerHeight += expandableListView.getDividerHeight() * (expandableListAdapter.getGroupCount()-1);
ViewGroup.LayoutParams params = expandableListView.getLayoutParams();
params.height = totalHeight + totalDividerHeight;
expandableListView.setLayoutParams(params);
expandableListView.requestLayout();
}
Android, you did made me lost a lot of time. GRRRRRR!
I've found another solution in a tutorial:
public class SecondLevelExpanableListView extends ExpandableListView {
public SecondLevelExpanableListView(Context context) {
super(context);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(999999, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
this worked for me!