0

I have a list view of the emails of all the contacts in the phonebook.My list is a custom listview with a checkbox.Now the problem is as follows.

For eg i have 20 emails in the list.If i select the first email say "A" in the list and then scrolls the list,other emails are also getting selected by itself.Also if i again scroll back to the list ,my selected email "A" is being deselected by it own. I dnot know why this is occuring

CustomList

public class EmailListAdapter extends BaseAdapter {
    private Context context;
    private ArrayList<String> data;
    DbHandler dbHandler;

    public EmailListAdapter(Context context, ArrayList<String> data) {
        this.context = context;
        this.data = data;
    }

    @Override

    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(final int i, View view, ViewGroup viewGroup) {

        final ViewHolder holder;
        dbHandler = new DbHandler(context);

        if (view == null) {
            holder = new ViewHolder();
            view = LayoutInflater.from(context).inflate(R.layout.email_custom_list, viewGroup, false);
            holder.tvContact = (TextView) view.findViewById(R.id.tv_email_name);
            holder.checkBox = (CheckBox) view.findViewById(R.id.cb_email_checkbox);

            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (compoundButton == holder.checkBox) {
                    if (b) {
//                        dbHandler.updateContactList(data.get(i).getUserID(), 1);

                    } else {
//                        dbHandler.updateContactList(data.get(i).getUserID(), 0);
                    }
                }
            }
        });


        holder.tvContact.setText(data.get(i));


        return view;
    }

    private class ViewHolder {
        TextView tvContact;
        CheckBox checkBox;

    }
Anuj
  • 402
  • 8
  • 16

3 Answers3

1

The Adapter is recycling your views. Let's look at the following example:
Your ListView shows 10 rows at once and the first row has a blue background color. Now If you start scrolling the 11th row will become visible and the first will be hidden.
Internally the system recycles your first row and uses it as the 11th. So your 11th row will be blue as well.

So in order to fix this you have to set the background color each time in your getView(...) function. In your example you have to save the state of the different CheckBoxes manually and reapply them in the getView-function.

Edit

Just found this post on StackOverflow. It's discussing this topic even more detailed: How ListView's recycling mechanism works

Solution

Following just the relevant parts:

private int[] mStates;

public EmailListAdapter(Context context, ArrayList<String> data) {
    this.context = context;
    this.data = data;
    mStates = new int[data.size()];
}

@Override
public View getView(final int position, View view, ViewGroup viewGroup) {
    //...

    if (mStates[position] == 0) {
        holder.checkbox.setChecked(false);
    } else {
        holder.checkbox.setChecked(true);
    }

    holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            if (compoundButton == holder.checkBox) {
                if (b) {
                    mStates[position] = 1;
                    //dbHandler.updateContactList(data.get(i).getUserID(), 1);

                } else {
                    mStates[position] = 0;
                    //dbHandler.updateContactList(data.get(i).getUserID(), 0);
                }
            }
        }
    });

    //...
}
Community
  • 1
  • 1
reVerse
  • 35,075
  • 22
  • 89
  • 84
  • I just added the relevant parts – reVerse Aug 25 '14 at 11:22
  • i tried your way but, now whenever i select a checkbox and scrolls the list,that particular checkbox is being unchecked – Anuj Aug 25 '14 at 11:35
  • I guess the `onCheckedChanged`isn't called?! Please use a `holder.checkbox.setOnClickListener(new OnClickListener(){...}` – reVerse Aug 25 '14 at 11:44
  • No i sloved it but calling the if condition aftr the checkdoncliclicklistner – Anuj Aug 25 '14 at 12:03
  • Sure if it's related to the issue. Otherwise please create a new post. – reVerse Aug 25 '14 at 13:51
  • ya it is realted.Now wat i want is that i wanna stored the data whch users hav checked in arraylist.but when ever user scrolls the list the data in array is getting cleared – Anuj Aug 25 '14 at 14:26
  • link to the question http://stackoverflow.com/questions/25488160/get-the-checked-item-in-the-arraylist – Anuj Aug 25 '14 at 14:27
0

Since you are using a view holder your check box get reused while scrolling.The same check box at top comes again at bottom while you scroll when you use view holder.

And when you scroll back to top the check box comes back may not be old one.

So you have to save each checklists state to a list and use it according to position as your text view.

sachithkn
  • 457
  • 1
  • 4
  • 13
0

Solved Ans

public class EmailListAdapter extends BaseAdapter {
        private Context context;
        private ArrayList<EmailModel> data;
        DbHandler dbHandler;
        int[] emails;
        ArrayList<String> emailSeperated;

        public EmailListAdapter(Context context, ArrayList<EmailModel> data) {
            this.context = context;
            this.data = data;
            emails = new int[data.size()];
        }

        @Override

        public int getCount() {
            return data.size();
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(final int i, View view, ViewGroup viewGroup) {

            final ViewHolder holder;
            dbHandler = new DbHandler(context);
            emailSeperated = new ArrayList<String>();

            if (view == null) {
                holder = new ViewHolder();
                view = LayoutInflater.from(context).inflate(R.layout.email_custom_list, viewGroup, false);
                holder.tvContact = (TextView) view.findViewById(R.id.tv_email_name);
                holder.checkBox = (CheckBox) view.findViewById(R.id.cb_email_checkbox);

                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }
    //        if (emails[i] == 0) {
    //            holder.checkBox.setChecked(false);
    //        } else {
    //            holder.checkBox.setChecked(true);
    //        }

            holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                                                           @Override
                                                           public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

                                                               if (compoundButton == holder.checkBox) {
                                                                   if (b) {
                                                                       emails[i] = 1;
                                                                       //dbHandler.updateContactList(data.get(i).getUserID(), 1);
                                                                       emailSeperated.add(data.get(i).getEmail());
                                                                       Log.e("Email values", emailSeperated.toString());

    //

                                                                   } else {
                                                                       emails[i] = 0;
                                                                       emailSeperated.remove(data.get(i).getEmail());
                                                                       Log.e("Email values", emailSeperated.toString());


                                                                   }
                                                               }

                                                           }
                                                       }

            );


            if (emails[i] == 0) {
                holder.checkBox.setChecked(false);
            } else {
                holder.checkBox.setChecked(true);
            }


            holder.tvContact.setText(data.get(i).

                            getEmail()

            );


            return view;
        }


        private class ViewHolder {
            TextView tvContact;
            CheckBox checkBox;

        }
    }
Anuj
  • 402
  • 8
  • 16