Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExpandableListView groupView checkbox unticking other groupviews

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;
        }
    }
}
like image 972
turtleboy Avatar asked Apr 28 '15 12:04

turtleboy


2 Answers

I haven't gone through your problem but based on the same, I have created a sample project for you, please try with it and i am sure that it will help you to resolve your issue.

Expandable Checklist

Output:-

enter image description here

like image 195
Abhishek Avatar answered Nov 12 '22 17:11

Abhishek


private Context myContext;

        class ViewHolder {
        public TextView groupName;
        public CheckBox groupCheckBox;

      } 
 ViewHolder viewHolder;
 @Override
  public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {

    if (convertView == null) {
    viewHolder = new ViewHolder();
    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) {
          // Write Your required code here//
        }
  // your other code//
   return convertView;
}

do this part on Activity/Fragment where your setting adapter

ExpandableListView mExpandableListView = (ExpandableListView) parent;
mExpandableListView.expandGroup(groupPosition);
like image 2
Ankit Kumar Avatar answered Nov 12 '22 17:11

Ankit Kumar