简体   繁体   中英

Expandable listview using checkbox

I am working on expandable listview using checkboxes. All the views of the child has seted properly. The problem is that if check checkbox the child view are checked randomly as while as if I expand groupview and child view it automatically selected if clarify the isssue binding the tag is not added to checkbox properly.

enter code here
             if (row == null)
     {
        holder=new ChildHolder();
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = infalInflater.inflate(R.layout.list_item_msg, null);
            holder. txtListChild = (TextView)                row.findViewById(R.id.msgtextID);
          holder.sendnow=(CheckBox)row.findViewById(R.id.sendnowID);
         list=_listDataChild.get(_listDataHeader.get(groupPosition)).get(childPosition);
        notifyDataSetChanged();


  holder.sendnow.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // TODO Auto-generated method stub
                      // ch.setChecked(buttonView.isChecked());  
                notifyDataSetChanged();
                // getPosition = (Integer) buttonView.getTag();

            if(isChecked)
            { 
                 contactsVo childText = (contactsVo) holder.sendnow.getTag();
                  childText = (contactsVo) getChild(groupPosition, childPosition);
                childText.setChecked(buttonView.isChecked());
                personals=new ArrayList<contactsVo>();
                set.add(list.getFileId());
                contactsVo obj1=new contactsVo();
                obj1.setImeiNo(list.getImeiNo());
                obj1.setUserId(list.getUserId());
                //obj.add(obj1);
                personals.add(obj1);
                Log.e("=================","========================");

            }else
            {
                Log.e("Uncheked","See it");
                set.remove(list.getFileId());

            }
        }
    });
  row.setTag(holder);
    holder.sendnow.setTag((contactsVo) getChild(groupPosition,childPosition));

    }else
    {
        row = convertView;
         ((ChildHolder) row.getTag()).sendnow.setTag((contactsVo) getChild(groupPosition,childPosition));
    }

    try
    {
         ChildHolder holder = (ChildHolder)row.getTag();
         childText = (contactsVo) getChild(groupPosition,childPosition);
         holder.txtListChild.setText(childText.getName());
     holder.sendnow.setChecked(((contactsVo) getChild(groupPosition,childPosition)).isChecked());


    }catch(Exception e)
    {
        e.printStackTrace();
    }

You should call notifyDataSetChanged() after doing change in adapter so your code should like given below.

 holder=new ChildHolder();
    LayoutInflater infalInflater = (LayoutInflater) this._context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    row = infalInflater.inflate(R.layout.list_item_msg, null);
        holder. txtListChild = (TextView)                row.findViewById(R.id.msgtextID);
      holder.sendnow=(CheckBox)row.findViewById(R.id.sendnowID);
     list=_listDataChild.get(_listDataHeader.get(groupPosition)).get(childPosition);
     // notifyDataSetChanged();


 holder.sendnow.setOnCheckedChangeListener(new OnCheckedChangeListener() {

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // TODO Auto-generated method stub
                  // ch.setChecked(buttonView.isChecked());  

            // getPosition = (Integer) buttonView.getTag();

        if(isChecked)
        { 
             contactsVo childText = (contactsVo) holder.sendnow.getTag();
              childText = (contactsVo) getChild(groupPosition, childPosition);
            childText.setChecked(buttonView.isChecked());
            personals=new ArrayList<contactsVo>();
            set.add(list.getFileId());
            contactsVo obj1=new contactsVo();
            obj1.setImeiNo(list.getImeiNo());
            obj1.setUserId(list.getUserId());
            //obj.add(obj1);
            personals.add(obj1);
            Log.e("=================","========================");

        }else
        {
            Log.e("Uncheked","See it");
            set.remove(list.getFileId());

        }

        notifyDataSetChanged();

    }
});

Checkboxes in listviews can get confusing, you can't rely on the view to know if a box has been checked or not you need to create a reference of booleans the same size as the items in your adapter and set the checkbox manually depending on if its true or false. Since views get recycled in a listview and you scroll the list some views will appear to be checked even though you haven't checked them yet. Don't set a checked change listener because that will fire when you scroll around. Here is an adapter I use with check boxes, every time getview is called you need to reference the boolean array to figure out if you want to check that box

class TagAdapter extends StandardAdapter {

boolean[] checkedItems;
int iconWidth;

public TagAdapter() {

    checkedItems = new boolean[items.size()];

    registerDataSetObserver(new DataSetObserver() {

        @Override
        public void onChanged() {
            super.onChanged();
            updateProperties();
        }

    });

    iconWidth = MyApp.getScreenWidth() / 7;
}

void updateProperties() {
    checkedItems = new boolean[items.size()];
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    final ViewHolder viewHolder;

    if (convertView == null) {

        convertView = mLayoutInflater.inflate(R.layout.checkin_friend, parent, false);

        viewHolder = new ViewHolder();

        viewHolder.ivIcon = (CachedImageView) convertView.findViewById(R.id.ivIcon);
        viewHolder.tvName = (TextView) convertView.findViewById(R.id.tvName);
        viewHolder.cbFriend = (CheckBox) convertView.findViewById(R.id.cbFriend);

        convertView.setTag(viewHolder);

    }
    else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    final JsonObject item = getItem(position);
    final Profile profile = new Gson().fromJson(item, Profile.class);

    viewHolder.tvName.setText(profile.getUsername());

    if (profile.getIcon() != null) {

        viewHolder.ivIcon.set(app.imageContainer + profile.getIcon(), true);

    }
    else {
        viewHolder.ivIcon.setImageDrawable(app.defaultIcon);

    }

    viewHolder.ivIcon.setLayoutParams(new RelativeLayout.LayoutParams(iconWidth, iconWidth));



    viewHolder.cbFriend.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {


        }
    });

    viewHolder.cbFriend.setChecked(checkedItems[position]);

    convertView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            boolean current = checkedItems[position];

            if (current == true) {

                boolean modified = tags.remove(profile);

                if(modified == false){
                    Log.d(MyApp.TAG,"modification was false");
                }
            }
            else {
                tags.add(profile);
            }

            checkedItems[position] = !current;

            viewHolder.cbFriend.setChecked(checkedItems[position]);

            updateUi();

        }
    });



    return convertView;

}

public class ViewHolder {
    CachedImageView ivIcon;
    TextView tvName;
    CheckBox cbFriend;
}

}

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