Ravin
Ravin

Reputation: 10538

mark of checkbox disappear on filter in a listview

I am trying to create list of contacts with checkbox in each item of the listview and name of the contact. I have written a filter which searches by name of the contact. The problem is when I filter through some name and then check that item and then delete or remove some text in the filter then the checkbox of the item which I checked before is disabled and basically a new view is getting created.

    public class ContactAdapter extends BaseAdapter implements Filterable{

    Context context;
    ArrayList<ContactItem> contactlist;
    ArrayList<ContactItem> mStringFilterList;
    ValueFilter valueFilter;

    public ContactAdapter(Context context , ArrayList<ContactItem> contactlist) {
        this.context = context;
        this.contactlist = contactlist;
        mStringFilterList = contactlist;
    }

    @Override
    public int getCount() {
        return contactlist.size();
    }

    @Override
    public Object getItem(int position) {
        return contactlist.get(position);
    }

    @Override
    public long getItemId(int position) {
        return contactlist.indexOf(getItem(position));
    }

    private class ViewHolder {
        TextView name;
        CheckBox selection;
        TextView phoneNumber;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        if (convertView == null) {
            LayoutInflater mInflater = (LayoutInflater) context
                    .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = mInflater.inflate(R.layout.adapter_item_contact,null);
            holder = new ViewHolder();
            holder.name = (TextView) convertView.findViewById(R.id.tv_name);
            holder.phoneNumber = (TextView) convertView.findViewById(R.id.tv_number);
            holder.selection = (CheckBox) convertView.findViewById(R.id.cb_contact);
            convertView.setTag(holder);

            holder.selection.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    CheckBox cb = (CheckBox) view;
                    ContactItem item = (ContactItem) cb.getTag();
                    item.setSelected(cb.isChecked());

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

        ContactItem contact = contactlist.get(position);
        holder.name.setText(contact.getName());
        holder.phoneNumber.setText(contact.getPhoneNumber());
        holder.selection.setTag(contact);
        holder.selection.setChecked(contact.isSelected());


        return convertView;
    }

    @Override
    public Filter getFilter() {
        if (valueFilter == null) {
            valueFilter = new ValueFilter();
        }
        return valueFilter;
    }

    private class ValueFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            if (constraint != null && constraint.length() > 0) {
                ArrayList<ContactItem> filterList = new ArrayList<ContactItem>();
                for (int i = 0; i < mStringFilterList.size(); i++) {
                    if ( (mStringFilterList.get(i).getName().toUpperCase() )
                            .contains(constraint.toString().toUpperCase())) {

                        ContactItem contact = new ContactItem(mStringFilterList.get(i)
                                .getName() ,  mStringFilterList.get(i)
                                .getPhoneNumber() ,  mStringFilterList.get(i)
                                .isSelected());

                        filterList.add(contact);
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
            } else {
                synchronized(this){
                    results.count = mStringFilterList.size();
                    results.values = mStringFilterList;
                }

            }
            return results;

        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
            contactlist = (ArrayList<ContactItem>) results.values;
            notifyDataSetChanged();
        }

    }

}

Upvotes: 0

Views: 571

Answers (2)

Ravin
Ravin

Reputation: 10538

Sandesh I am storing the item state each time get view is called as you can see by using setTag and getTag on the checkboxes. I have Solved the issue now. The problem was I was creating new contact item each time the filter was called so the previous contact item was gone.

Problematic code is below

private class ValueFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            if (constraint != null && constraint.length() > 0) {
                ArrayList<ContactItem> filterList = new ArrayList<ContactItem>();
                for (int i = 0; i < mStringFilterList.size(); i++) {
                    if ( (mStringFilterList.get(i).getName().toUpperCase() )
                            .contains(constraint.toString().toUpperCase())) {

                        ContactItem contact = new ContactItem(mStringFilterList.get(i)
                                .getName() ,  mStringFilterList.get(i)
                                .getPhoneNumber() ,  mStringFilterList.get(i)
                                .isSelected());

                        filterList.add(contact);
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
            } else {
                synchronized(this){
                    results.count = mStringFilterList.size();
                    results.values = mStringFilterList;
                }

            }
            return results;

        }

Solved Code. I had to add the same filter objects which i got from the mStringFilterList in the filterlist.

private class ValueFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            if (constraint != null && constraint.length() > 0) {
                ArrayList<ContactItem> filterList = new ArrayList<ContactItem>();
                for (int i = 0; i < mStringFilterList.size(); i++) {
                    if ( (mStringFilterList.get(i).getName().toUpperCase() )
                            .contains(constraint.toString().toUpperCase())) {

//                        ContactItem contact = new ContactItem(mStringFilterList.get(i)
//                                .getName() ,  mStringFilterList.get(i)
//                                .getPhoneNumber() ,  mStringFilterList.get(i)
//                                .isSelected());

                        filterList.add(mStringFilterList.get(i));
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
            } else {
                synchronized(this){
                    results.count = mStringFilterList.size();
                    results.values = mStringFilterList;
                }

            }
            return results;

        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
            contactlist = (ArrayList<ContactItem>) results.values;
            notifyDataSetChanged();
        }

    }

Upvotes: 3

sandesh hegde
sandesh hegde

Reputation: 34

Each time some changes happens in listView like scrolling through the list , getView Method is called every time. So you have store which items in the list are checked in an array and in getView method check the items which are present in the list .

Or you may do like this : Check for 14.2. Tutorial: Domain Model and Rows interaction in below link

Link

Upvotes: 1

Related Questions