I have the following adapter in my Activity
. I have set a CheckBox
on the GroupView
that when touched will check/uncheck the child views (which also have a CheckBox
).
The state of the CheckBox(true or false)
is stored in the DB and initially set to true/checked. The checkboxes are set to checked initially.
There is some strange behaviour when I touch a GroupCheckbox
, it also unchecks the checkbox that are not part of the GroupView
that has been touched.
So for example if I have 5 GroupViews
and each GroupView
has 5 children.
If I uncheck the 1st GroupView
CheckBox
, it unchecks all its children but also the 3rd GroupView
CheckBox
and its children.
Are there any ideas why?
[Edit 1]
I've deleted previous code snippets as I'm starting a bounty. The code has changed from the original as Ankit Kumar has helped me with the Viewholder patter in getGroupView
method. It still unchecks multiple groupview checkboxes when only one checkbox is touched. the backing DB has all the states of the checkboxes checked as true
to start with.
It would seem that the view is out of sync with the DB. I've logged out statements that prove the state of all checkboxes are true to start with.
Is there a way to only make the checkbox the user touches uncheck without effecting the other checkboxes?
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;
int companyCount;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.e(TAG, "oncreate");
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 {
companyCount = companies.getCount();
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));
for(int h = 0; h < companyCount; h++){
expList.expandGroup(h);
}
expList.setOnGroupExpandListener(new OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
Log.e("onGroupExpand", "OK");
Log.e("groupPosition", " " + groupPosition);
}
});
// expList.setOnGroupClickListener(new OnGroupClickListener() {
//
// @Override
// public boolean onGroupClick(ExpandableListView parent, View v,
// int groupPosition, long id) {
//
//
// Log.e(TAG, "groupPosition in onGroupClickListener = " + groupPosition);
//
// int count = 0;
//
// for (int i = 0; i < arrChildelements[groupPosition].length; i++){
//
// if(arrChildelements[groupPosition][i] != null){
//
// count += arrChildelements[groupPosition][i] != null ? 1 : 0;
//
// Log.e("TAG", "child count in onGroupClickListener = " + count);
// Log.e(TAG, "arrChildelements[groupPosition][i] = " + arrChildelements[groupPosition][i]);
//
// int branchID = appObj.dbModel.getBranchIdFromName(arrChildelements[groupPosition][i]);
//
// appObj.dbModel.updateBranchSelectedStatus(String.valueOf(branchID), "N");
//
//
//
// }//end of if
//
// }//end of for loop
//
//
//
// return false;
// }
// });
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);
String companyName = arrGroupelements[groupPosition];
Log.e(TAG, "**********CompanyName = " + companyName);
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, "Branches selected are " + appObj.dbModel.getBranchList());
if(appObj.dbModel.isCompanySelected(companyName) == false){
//set companySeelcted to false
appObj.dbModel.updateCompanySelectedStatus(companyName, "N");
Log.e(TAG, "Setting company to no longer selected as no branches are selected for " + companyName);
}
}
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());
//set company to selected
appObj.dbModel.updateCompanySelectedStatus(companyName, "Y");
}
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;
class ViewHolder {
public TextView groupName;
public CheckBox groupCheckBox;
}
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;
Log.e(TAG, "getChildrenCount");
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() {
Log.e(TAG, "getGroupCount");
return arrGroupelements.length;
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
ViewHolder viewHolder;
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
Log.e(TAG, "getGroupView");
viewHolder = new ViewHolder();
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.group_row, null);
viewHolder.groupName = (TextView) convertView.findViewById(R.id.tvGroupName);
viewHolder.groupCheckBox = (CheckBox) convertView.findViewById(R.id.groupcheckbox);
convertView.setTag(viewHolder);
} else viewHolder = (ViewHolder) convertView.getTag();
final ViewHolder holder = viewHolder;
holder.groupName.setText(arrGroupelements[groupPosition]);
holder.groupCheckBox.setTag(groupPosition);
holder.groupCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int pos = (Integer) holder.groupCheckBox.getTag();
Log.e(TAG, "oncheckChanged has fired at position " + pos);
int yCount = 0;
Cursor c = appObj.dbModel.queryAllFromCompanyBranch();
c.moveToFirst();
do {
String str = c.getString(c.getColumnIndex(DBModel.C_COMPANYBRANCH_SELECTED));
if(str.equalsIgnoreCase("Y")) {
yCount++;
}
} while(c.moveToNext());
Log.e(TAG, "yCount before = " + yCount);
if(isChecked == true) {
Log.e(TAG, "checkBox true");
int count = 0;
for (int i = 0; i < getChildrenCount(pos); i++) {
if(arrChildelements[pos][i] != null) {
count += arrChildelements[pos][i] != null ? 1 : 0;
Log.e("TAG", "child count in onGroupClickListener = " + count);
Log.e(TAG, "arrChildelements[groupPosition][i] = " + arrChildelements[pos][i]);
int branchID = appObj.dbModel.getBranchIdFromName(arrChildelements[pos][i]);
appObj.dbModel.updateBranchSelectedStatus(String.valueOf(branchID), "Y");
appObj.dbModel.updateCompanySelectedStatus(arrGroupelements[pos], "Y");
}//end of if
}//end of for loop
}
else if(isChecked == false) {
Log.e(TAG, "checkBox false");
int count = 0;
for (int i = 0; i < getChildrenCount(pos); i++) {
if(arrChildelements[pos][i] != null) {
count += arrChildelements[pos][i] != null ? 1 : 0;
Log.e("TAG", "child count in onGroupClickListener = " + count);
Log.e(TAG, "arrChildelements[groupPosition][i] = " + arrChildelements[pos][i]);
int branchID = appObj.dbModel.getBranchIdFromName(arrChildelements[pos][i]);
appObj.dbModel.updateBranchSelectedStatus(String.valueOf(branchID), "N");
appObj.dbModel.updateCompanySelectedStatus(arrGroupelements[pos], "N");
Log.e(TAG, "Setting company to no longer selected as no branches are selected for " + arrGroupelements[pos]);
}//end of if
}//end of for loop
}
int yCount2 = 0;
Cursor c2 = appObj.dbModel.queryAllFromCompanyBranch();
c2.moveToFirst();
do {
String str2 = c2.getString(c2.getColumnIndex(DBModel.C_COMPANYBRANCH_SELECTED));
if(str2.equalsIgnoreCase("Y")){
yCount2++;
}
} while(c2.moveToNext());
Log.e(TAG, "yCount2 after = " + yCount2);
notifyDataSetChanged();
}
});
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;
}
}
}
RadioButtons
(same concept) is to store an id of each child in aHashMap<String, Boolean>
and whether it is checked or not. I also had to set them all to unchecked each time through then check if the id is in the list ingetChildView()
and set it accordingly. – Bluet