简体   繁体   中英

Android: Dynamically marking checkboxes in ExpandableListView

I am using ExpandableListView, and the child row each has a textview, and checkbox within it.

What I want to do is, when a user pushes a button, the activity figures out which items are 'checked' and do something with those items.

I read many posts on how ExpandableListView and checkboxes currently don't work well, and how I need to keep an additional data structure to keep track of what's has been selected, and not. This post covers that issue: ExpandableListView and checkboxes

Done! I now can keep track of what's been selected, and what's not been selected.

Now I want to tackle the problem of check boxes not showing their states. I have noticed that the check boxes change randomly when:

  • screen rotation changes
  • a group collapses/opens

I know that it's possible to detect these events.

I want to know if there's a way to set the check boxes by hand. I initially tried

ExpandableListView elv = getExpandableListView();
for(int i = 0; i < elv.getChildCount(); i++) {
  CheckBox checkbox = ... somehow get checbox within the list
  checkbox.setChecked(checkList.at(i, j));
}

where i, and j indicate which group, and children, and checkList keeps track of checked/unchecked items.

However, I noticed that value of getChildCount() depends on how many groups are open, and does not necessarily tell me which list item I can manipulate.

ExpandableListView has been used, and someone must have had a way of getting around this issue. Is there a smart solution to this? Specifically, I am looking for ways to check/uncheck appropriate items in the list at onGroupExpand and onConfigurationChange (or similar events.)

Thank you in advance!

Check following sample Expandable list adapter

/**
     * A simple adapter which maintains an ArrayList of photo resource Ids. 
     * Each photo is displayed as an image. This adapter supports clearing the
     * list of photos and adding a new photo.
     *
     */
    public class MyExpandableListAdapter extends BaseExpandableListAdapter {


        // Sample data set.  children[i] contains the children (String[]) for groups[i].
        private String[] groups = { "People Names", "Dog Names", "Cat Names", "Fish Names" };
        private String[][] children = {
                { "Arnold", "Barry", "Chuck", "David" },
                { "Ace", "Bandit", "Cha-Cha", "Deuce" },
                { "Fluffy", "Snuggles" },
                { "Goldy", "Bubbles" }
        };

        private ArrayList<ArrayList<Boolean>> checkboxStatus = new ArrayList<ArrayList<Boolean>>();

        public MyExpandableListAdapter() {
            int groupCount = groups.length;
            for(int i=0; i<groupCount; i++) 
            {
                int childCount = children[i].length;
                ArrayList<Boolean> childStatus = new ArrayList<Boolean>();
                for(int j=0; j<childCount; j++) {
                    childStatus.add(false);
                }
                checkboxStatus.add(childStatus);
            }
        }

        public Object getChild(int groupPosition, int childPosition) {
            return children[groupPosition][childPosition];
        }

        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }

        public int getChildrenCount(int groupPosition) {
            return children[groupPosition].length;
        }

        public TextView getGenericView() {

            // Layout parameters for the ExpandableListView
            AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, 64);

            TextView textView = new TextView(ExpandableListCheckboxActivity.this);
            textView.setLayoutParams(lp);
            // Center the text vertically
            textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
            // Set the text starting position
            textView.setPadding(36, 0, 0, 0);
            return textView;
        }

        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
                View convertView, ViewGroup parent) {

            CheckBox chkbox = new CheckBox(ExpandableListCheckboxActivity.this);
            chkbox.setTag("" + groupPosition + "," + childPosition);
            chkbox.setOnCheckedChangeListener(checkboxListener);
            chkbox.setText(children[groupPosition][childPosition]);

            chkbox.setChecked(checkboxStatus.get(groupPosition).get(childPosition));

            return chkbox;
        }

        public Object getGroup(int groupPosition) {
            return groups[groupPosition];
        }

        public int getGroupCount() {
            return groups.length;
        }

        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
                ViewGroup parent) {
            TextView textView = getGenericView();
            textView.setText(getGroup(groupPosition).toString());

            return textView;
        }

        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }

        public boolean hasStableIds() {
            return true;
        }

        private OnCheckedChangeListener checkboxListener = new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                String positions = buttonView.getTag().toString();
                int groupPosition = Integer.valueOf(positions.split(",")[0]);
                int childPosition = Integer.valueOf(positions.split(",")[1]);
                checkboxStatus.get(groupPosition).set(childPosition, isChecked);
            }
        };

    }

If you just want it to change upon clicking the row:

elv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
    @Override
    public boolean onChildClick(ExpandableListView parent, View v,
            int groupPosition, int childPosition, long id) {
        CheckBox checkbox = (CheckBox) v.findViewById(r.id.yourcheckbox)
        checkbox.setChecked(checkList.at(groupPosition, childPosition));    
        return true;
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM