Android listview with checkbox problem
Asked Answered
S

2

25

I have a weird problem! I'm trying to create a listview with checkboxes. In my other thread I was told that I should use an array that keeps track of the rows that are checked. I did that and it worked fine-ish but the logic is wrong and I run into another problem now.

public View getView(final int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.row, null);
        }

        CheckBox checkbox = (CheckBox)v.findViewById(R.id.checkbox);
        checkbox.setChecked(checked[position]);

        final LinearLayout rowLayout = (LinearLayout) v.findViewById(R.id.individualRow);

        checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener(){

            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked)
                {
                    rowLayout.setBackgroundColor(Color.GRAY);                       
                    checked[position] = false;                      
                }
                else
                {   
                    rowLayout.setBackgroundColor(Color.DKGRAY);
                    checked[position] = true;                       
                }
            }               
        });
   }

Having all the checkboxes unchecked initially it works fine it keeps the ones that i select checked even if I scroll down and back up again but the checked array is not properly set up. Basically the if test should be the other way arround!

if(isChecked)
{
   rowLayout.setBackgroundColor(Color.GRAY);                        
   checked[position] = true;                        
}
else
{   
   rowLayout.setBackgroundColor(Color.DKGRAY);
   checked[position] = false;                       
}

The problem is with the scroll really because every time I scroll the onCheckedChanged method is called and since its recycling the rows it passes in the position of the new row that its not selected but since it has the same index as the one that was previously selected it changes its value. for example if I check the box with index 2 (set it to true) and then scroll down a new row becomes row with index 2, the method is called again and it unsets the checkbox(the field in the checked array).

I need it to "remember" all the boxes that are checked. In other words I want the checked array to be initialised properly. And also to remember which boxes are checked and not lose them everytime I scroll!

What am I doing wrong?

Can you please help me?

Thanks in advance -- Mike

Sandman answered 26/3, 2011 at 18:30 Comment(3)
Hey mixkat can you elaborate more on the use of the array?Credendum
Can you show where you fill the boolean array???Credendum
was having same issue but with switch instead, but didn't thought solution is that much simpleSilicic
S
78

This was tricky.

The problem is that you are calling setChecked, activating the old OnCheckedChangeListener.

The fix is quite simple: call setOnCheckedChangeListener before calling setChecked. This way you sever the link to the old listener from the recycled view.

Settee answered 27/3, 2011 at 3:1 Comment(9)
You blow my mind! That did fix it! Theres no chance I could have seen that! Thanks!Sandman
Yeah, I didn't realize that setChecked would trigger the OnCheckedChangeListener. Lesson learned!Settee
Have a look at Vikas' answer too if you want! it works quite well! And its actually easier in terms of "logic" or "flow of events"!Sandman
I thought about this for a second, but didn't try myself initially, and wasted hours on this unnecessarily, till i read here that it actually works!!! So upvoteSilicic
please post your sample code, sorry but i don't know how to solved this problemDisk
Your code works except for the first time I check an item and scroll away. Subsequently, it works just fine. How can I fix this?Bristol
Perfect! It works! Here, I add my code below. final Data d = DataList.get(i); viewHolder.cbCompany.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { d.setEnabled(isChecked); } }); viewHolder.cbCompany.setChecked(d.isEnabled());Ermine
WOW, you are a hero! I spent more than 2 hours saying 'what the hell going on? '. +1Poodle
Thankssss youuuuuuuuu !Weiweibel
E
0

Check this for Single selection of Checkbox in Listview

AdpList adapter=new AdpList(this,array,false);
listview.setAdapter(adapter);

When you select any Item then on item CLickListener do as Follows

listview.setonItemClickListener(new OnItemClickListener)

Here You will Get the Position of the Current Item

array.get(Position);

Get the Checkbox view and On clicking the Checkbox, create a method in Adapter, Like

adapter.setList(true);
adapter.notifyDataSetChanged();

And In Adapter check the Parameter that I have Passed in the Setlist method then put condition:

if (isChecking==true)
{
checkbox1.setChecked(true);
}else{
checkBox1.setChecked(false);
}
Elboa answered 10/9, 2015 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.