CheckBox在ExpandableListView的子节点中声明

 右心1477 发布于 2023-01-30 05:33

我已经从SO阅读了大约30页以及有关在列表中跟踪检查状态的教程,但是在可扩展ListView中这样做很少有信息(尤其是工作信息).

我让孩子们填充了复选框,但当我检查一组孩子的盒子时,其他组中的随机孩子也会检查.我需要阻止这一点.我认为我读到的最好的信息是将复选框设置为单独的标签,但我不知道如何设置多个标签,当我尝试时,我遇到了类错配错误,将复选框与转换视图进行比较.

有没有人遇到过在expandablelistview的孩子中跟踪复选框状态的好方法?

我做了多处更改,所以我要输入整个适配器代码.请检查几行getGroupView和整个getChildView,并帮我看看我做错了什么.

编辑:现在发生的事情是,当我选中一个框然后展开另一个组时,所有选中的框都取消选中:

public class MyExpandableListAdapter extends BaseExpandableListAdapter
    implements OnCheckedChangeListener {

private Context mContext;

private ArrayList mListDataHeader;
private HashMap> mListDataChild;

private boolean[] mGetChecked;
private HashMap mChildCheckStates;

private ArrayList selectedNumbers;

private ChildViewHolder childViewHolder;
private GroupViewHolder groupViewHolder;

private String numberText;

public MyExpandableListAdapter(Context context,
        ArrayList listDataHeader,
        HashMap> listDataChild,
        ArrayList listOfNumbers) {

    mContext = context;
    mListDataHeader = listDataHeader;
    mListDataChild = listDataChild;
    selectedNumbers = listOfNumbers;

    mChildCheckStates = new HashMap();
}

@Override
public int getGroupCount() {
    return mListDataHeader.size();
}

@Override
public ContactNameItems getGroup(int groupPosition) {
    return mListDataHeader.get(groupPosition);
}

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

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent) {

    String contactName = getGroup(groupPosition).getName();
    Bitmap contactImage = getGroup(groupPosition).getImage();

    mGetChecked = new boolean[getChildrenCount(groupPosition)];
    mChildCheckStates.put(contactName, mGetChecked);

    if (convertView == null) {

        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.contact_name_item, null);

        groupViewHolder = new GroupViewHolder();

        groupViewHolder.mContactName = (TextView) convertView
                .findViewById(R.id.lblListHeader);

        groupViewHolder.mContactImage = (ImageView) convertView
                .findViewById(R.id.ivContactPhoto);

        convertView.setTag(groupViewHolder);
    } else {

        groupViewHolder = (GroupViewHolder) convertView.getTag();
    }

    if (contactImage != null) {
        groupViewHolder.mContactImage.setImageBitmap(contactImage);

    } else {
        groupViewHolder.mContactImage
                .setImageResource(R.drawable.default_contact);
    }

    groupViewHolder.mContactName.setText(contactName);

    return convertView;
}

@Override
public int getChildrenCount(int groupPosition) {
    return mListDataChild.get(mListDataHeader.get(groupPosition).getName())
            .size();
}

@Override
public ContactPhoneItems getChild(int groupPosition, int childPosition) {
    return mListDataChild.get(mListDataHeader.get(groupPosition).getName())
            .get(childPosition);
}

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

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

    final String contactName = getGroup(groupPosition).getName();
    final int mChildPosition = childPosition;

    numberText = getChild(groupPosition, childPosition).getNumber();
    String typeText = getChild(groupPosition, childPosition).getPhoneType();

    mGetChecked = mChildCheckStates.get(contactName);

    if (convertView == null) {

        LayoutInflater inflater = (LayoutInflater) this.mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.contact_detail_item, null);

        childViewHolder = new ChildViewHolder();

        childViewHolder.mPhoneNumber = (TextView) convertView
                .findViewById(R.id.tv_phone_number);

        childViewHolder.mPhoneType = (TextView) convertView
                .findViewById(R.id.tv_phone_type);

        childViewHolder.mCheckBox = (CheckBox) convertView
                .findViewById(R.id.checkBox);

        convertView.setTag(R.layout.contact_detail_item, childViewHolder);

    } else {

        childViewHolder = (ChildViewHolder) convertView
                .getTag(R.layout.contact_detail_item);
    }

    childViewHolder.mPhoneNumber.setText(numberText);
    childViewHolder.mPhoneType.setText(typeText);

    childViewHolder.mCheckBox.setChecked(mGetChecked[mChildPosition]);
    childViewHolder.mCheckBox.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            boolean isChecked = childViewHolder.mCheckBox.isChecked();

            Log.d("Debug", "isChecked = " + String.valueOf(isChecked));

            if (isChecked) {

                selectedNumbers.add(numberText);

            } else {

                selectedNumbers.remove(numberText);
            }

            childViewHolder.mCheckBox.setChecked(isChecked);

            mGetChecked[mChildPosition] = isChecked;
            mChildCheckStates.put(contactName, mGetChecked);
        }
    });

    return convertView;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return false;
}

@Override
public boolean hasStableIds() {
    return false;
}

public ArrayList getSelectedNumbers() {

    return selectedNumbers;

}

public final class GroupViewHolder {

    TextView mContactName;
    ImageView mContactImage;
}

public final class ChildViewHolder {

    TextView mPhoneNumber;
    TextView mPhoneType;
    CheckBox mCheckBox;
}

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    // TODO Auto-generated method stub
    Log.d("Debug", "onCheckChangedListener : " + String.valueOf(isChecked));
}

}

1 个回答
  • 这是工作解决方案

    好的,虽然互联网上似乎有很多关于可扩展列表视图中的复选框的建议,但没有一个对我有用.我能够在一群人的帮助下得到它,尤其是dev84.现在我不会声称这是完美的或万无一失的.我只是声称它对我有用.我已经在2台设备上进行了测试,我对此非常满意.

    所以我已经把我的工作代码缩小到了它的基本部分,并添加了一些有用的评论,所以任何需要它的人都可以.希望它对你来说和我一样好用.请享用

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseExpandableListAdapter;
    import android.widget.CheckBox;
    import android.widget.CompoundButton;
    import android.widget.CompoundButton.OnCheckedChangeListener;
    import android.widget.TextView;
    
    // Eclipse wanted me to use a sparse array instead of my hashmaps, I just suppressed that suggestion
    @SuppressLint("UseSparseArrays")
    public class MyExpandableListAdapter extends BaseExpandableListAdapter {
    
        // Define activity context
        private Context mContext;
    
        /*
         * Here we have a Hashmap containing a String key 
         * (can be Integer or other type but I was testing 
         * with contacts so I used contact name as the key)
        */ 
        private HashMap<String, List<ExpListChildItems>> mListDataChild;
    
        // ArrayList that is what each key in the above 
        // hashmap points to
        private ArrayList<ExpListGroupItems> mListDataGroup;
    
        // Hashmap for keeping track of our checkbox check states
        private HashMap<Integer, boolean[]> mChildCheckStates;
    
        // Our getChildView & getGroupView use the viewholder patter
        // Here are the viewholders defined, the inner classes are
        // at the bottom
        private ChildViewHolder childViewHolder;
        private GroupViewHolder groupViewHolder;
    
        /*  
         *  For the purpose of this document, I'm only using a single
         *  textview in the group (parent) and child, but you're limited only
         *  by your XML view for each group item :)
        */ 
        private String groupText;
        private String childText
    
        /*  Here's the constructor we'll use to pass in our calling
         *  activity's context, group items, and child items
        */ 
        public MyExpandableListAdapter(Context context,
                ArrayList<ExpListGroupItems> listDataGroup, HashMap<String, List<ExpListChildItems>> listDataChild) {
    
            mContext = context;
            mListDataGroup = listDataGroup;
            mListDataChild = listDataChild;
    
            // Initialize our hashmap containing our check states here
            mChildCheckStates = new HashMap<Integer, boolean[]>();
        }
    
        @Override
        public int getGroupCount() {
            return mListDataGroup.size();
        }
    
        /*  
         * This defaults to "public object getGroup" if you auto import the methods
         * I always make a point to change it from "object" to whatever item
         * I passed through the constructor
        */ 
        @Override
        public ExpListGroupItems getGroup(int groupPosition) {
            return mListDataGroup.get(groupPosition);
        }
    
        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }
    
        @Override
        public View getGroupView(int groupPosition, boolean isExpanded,
                View convertView, ViewGroup parent) {
    
            //  I passed a text string into an activity holding a getter/setter
            //  which I passed in through "ExpListGroupItems".
            //  Here is where I call the getter to get that text
            groupText = getGroup(groupPosition).getGroupText();
    
            if (convertView == null) {
    
                LayoutInflater inflater = (LayoutInflater) mContext
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.group_item, null);
    
                // Initialize the GroupViewHolder defined at the bottom of this document
                groupViewHolder = new GroupViewHolder();
    
                groupViewHolder.mGroupText = (TextView) convertView.findViewById(R.id.groupTextView);
    
                convertView.setTag(groupViewHolder);
            } else {
    
                groupViewHolder = (GroupViewHolder) convertView.getTag();
            }
    
            groupViewHolder.mGroupText.setText(groupText);
    
            return convertView;
        }
    
        @Override
        public int getChildrenCount(int groupPosition) {
            return mListDataChild.get(mListDataGroup.get(groupPosition).getMyText()).size();
        }
    
        /*  
         * This defaults to "public object getChild" if you auto import the methods
         * I always make a point to change it from "object" to whatever item
         * I passed through the constructor
        */ 
        @Override
        public ExpListChildItems getChild(int groupPosition, int childPosition) {
            return mListDataChild.get(mListDataGroup.get(groupPosition).getMyText()).get(childPosition);
        }
    
        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }
    
        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    
            final int mGroupPosition = groupPosition;
            final int mChildPosition = childPosition;
    
            //  I passed a text string into an activity holding a getter/setter
            //  which I passed in through "ExpListChildItems".
            //  Here is where I call the getter to get that text
            childText = getChild(mGroupPosition, mChildPosition).getChildText();
    
            if (convertView == null) {
    
                LayoutInflater inflater = (LayoutInflater) this.mContext
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.child_item, null);
    
                childViewHolder = new ChildViewHolder();
    
                childViewHolder.mChildText = (TextView) convertView
                        .findViewById(R.id.childTextView);
    
                childViewHolder.mCheckBox = (CheckBox) convertView
                        .findViewById(R.id.checkBox);
    
                convertView.setTag(R.layout.child_item, childViewHolder);
    
            } else {
    
                childViewHolder = (ChildViewHolder) convertView
                        .getTag(R.layout.child_item);
            }
    
            childViewHolder.mChildText.setText(childText);
                /* 
             * You have to set the onCheckChangedListener to null
             * before restoring check states because each call to 
             * "setChecked" is accompanied by a call to the 
             * onCheckChangedListener
            */ 
            childViewHolder.mCheckBox.setOnCheckedChangeListener(null);
    
            if (mChildCheckStates.containsKey(mGroupPosition)) {
                /*
                 * if the hashmap mChildCheckStates<Integer, Boolean[]> contains
                 * the value of the parent view (group) of this child (aka, the key),
                 * then retrive the boolean array getChecked[]
                */
                boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
    
                // set the check state of this position's checkbox based on the 
                // boolean value of getChecked[position]
                childViewHolder.mCheckBox.setChecked(getChecked[mChildPosition]);
    
            } else {
    
                /*
                * if the hashmap mChildCheckStates<Integer, Boolean[]> does not
                * contain the value of the parent view (group) of this child (aka, the key),
                * (aka, the key), then initialize getChecked[] as a new boolean array
                *  and set it's size to the total number of children associated with 
                *  the parent group
                */
                boolean getChecked[] = new boolean[getChildrenCount(mGroupPosition)];
    
                // add getChecked[] to the mChildCheckStates hashmap using mGroupPosition as the key
                mChildCheckStates.put(mGroupPosition, getChecked);
    
                // set the check state of this position's checkbox based on the 
                // boolean value of getChecked[position]
                childViewHolder.mCheckBox.setChecked(false);
            }
    
            childViewHolder.mCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
    
                            if (isChecked) {
    
                                    boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
                                    getChecked[mChildPosition] = isChecked;
                                    mChildCheckStates.put(mGroupPosition, getChecked);
    
                            } else {
    
                                    boolean getChecked[] = mChildCheckStates.get(mGroupPosition);
                                    getChecked[mChildPosition] = isChecked;
                                    mChildCheckStates.put(mGroupPosition, getChecked);
                            }
                        }
                    });
    
            return convertView;
        }
    
        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return false;
        }
    
        @Override
        public boolean hasStableIds() {
            return false;
        }
    
        public final class GroupViewHolder {
    
            TextView mGroupText;
        }
    
        public final class ChildViewHolder {
    
            TextView mChildText;
            CheckBox mCheckBox;
        }
    }
    

    2023-01-30 06:08 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有