1

I'm facing with one problem, it's about disappearing checked items in listview when I'm scrolling the list and I don't know what to do.

Here is my code of custom adapter:

public class SPCKontrola extends Activity {
ArrayList<Integer> yourSelectedItems= new ArrayList<Integer>();

@Override
        public void onResume() {
            super.onResume();

            yourSelectedItems.clear();

        }
}

public class SPCMjereAdapter extends BaseAdapter 
    {
        private Context context;

        public SPCMjereAdapter(Context c) 
        {           
            context = c;                    
        }

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

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }
        public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") );

            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));

            CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
            Chk.setTag(MyArrList.get(position).get("RbMjere"));



Chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {               
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if(isChecked){
                            yourSelectedItems.add(position);
                        }else{
                            if(yourSelectedItems.contains(position)){                                               
                                yourSelectedItems.remove((position));                                   
                            }
                        }
                    }
                    });


            return convertView;

        }
}

What should I change or add in code? I have found some examples but I can't reuse non of them and implement in my code :/

Cœur
  • 37,241
  • 25
  • 195
  • 267
Josef
  • 2,648
  • 5
  • 37
  • 73
  • https://groups.google.com/forum/#!topic/android-developers/No0LrgJ6q2M. check the comment by Romain Guy. – Raghunandan Sep 28 '13 at 17:41
  • hm... seems a good solution but it extends ListActivity. I'm trying to avoid this because it will affect to some things in almost finished app. – Josef Sep 28 '13 at 17:47

7 Answers7

5

for this you have to maintain an array variable yourSelectedItems[] for storing the view positions that you have checked..and put a condition like this in your getView() method..

if(yourSelectedItems.contains((position))){
    check.setChecked(true);
}else{
    check.setChecked(false);
}

you can manage you array by writing this method in your getView()..

 check.setOnCheckedChangeListener(new OnCheckedChangeListener() {               
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if(isChecked){
            yourSelectedItems.add(position);
        }else{
            if(yourSelectedItems.contains(position)){                                               
                yourSelectedItems.remove((position));                                   
            }
        }
    });
David Brown
  • 35,411
  • 11
  • 83
  • 132
Vikram Singh
  • 1,420
  • 14
  • 19
  • Unfortunately this doesn't work. If I choose frist item than scroll list down it automatically checks some other items. If I go back to the top of list where is first item the item isn't checked any more. – Josef Sep 28 '13 at 22:43
  • it should not behave like that...can u post your changed code...?? – Vikram Singh Sep 29 '13 at 06:05
  • I've just add ArrayList yourSelectedItems = new ArrayList(); and make changes in getView() as you suggested me. – Josef Sep 29 '13 at 07:21
  • 1
    If you use ArrayList, you have to place true/false at respective position and match condition will also be different..so we have to change whole code for that...instead you can use your arraylist to be of Integer type, like this... ArrayList yourSelectedItems= new ArrayList();...then it will work... – Vikram Singh Sep 29 '13 at 07:31
  • Hm... I've changed now... I have 9 items in listview. If I check frist one, than scrool down and check the last one somehow the 4th items is also checked. That's litte bit weird. Also If I uncheck one of the items the program crashes: java.lang.IndexOutOfBoundsException: Invalid index 8, size is 3 – Josef Sep 29 '13 at 07:47
  • it is clearly showing that there is problem in adding and removing positions...dont forget to clean your array when you are coming to your activity again...usually in onResume()... the logic is fine, you just have to implement it properly.. – Vikram Singh Sep 29 '13 at 07:55
  • Sorry, but I don't get it. Everything is done by your instructions but still works on a strange way. I'm totally confused with listview especially beacuse i'm novice... – Josef Sep 29 '13 at 08:13
  • 1
    dont worry..custom adapter always keeps on troubling even experienced android developers.....put your new code in question..let me see whats the problem..:) – Vikram Singh Sep 29 '13 at 10:00
1

try this example for listview with check box:http://lalit3686.blogspot.in/2012/06/today-i-am-going-to-show-how-to-deal.html

Shivang Trivedi
  • 2,182
  • 1
  • 20
  • 26
1

To avoid the problems with CheckBoxes in a ListView you can take a Boolean array initialized false in the beginning and then making true the corresponding position in the array where checkbox is checked in the ListView. This will not cause a trouble in checked state of checkboxes when you move forward and backward in your application or scroll the ListView.You can check sample code here:

Android checkbox multiselected issue

Community
  • 1
  • 1
Rishabh Srivastava
  • 3,683
  • 2
  • 30
  • 58
1

This happened to me and i solve this wtih,

1.Create a global boolean arraylist and fill it with MyArrList.size() on constructor.

2.When you changed checkbox value set arratlist with views index.

3.Change this:

 CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
 Chk.setTag(MyArrList.get(position).get("RbMjere"));

with this:

 CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
 Chk.setTag(MyArrList.get(position).get("RbMjere"));
 Chk.setChecked(commentTexts.get(position));
invisbo
  • 3,399
  • 1
  • 16
  • 20
1

change your getview() with this one...

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

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") );

            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));

            CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);


             if(yourSelectedItems.contains((position))){
                Chk.setChecked(true);
             }else{
                Chk.setChecked(false);
             }

            Chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {               
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if(isChecked){
                            yourSelectedItems.add(position);
                        }else{
                            if(yourSelectedItems.contains(position)){                                               
                                yourSelectedItems.remove((position));                                   
                            }
                        }
                    }
                    });


            return convertView;

        }
Vikram Singh
  • 1,420
  • 14
  • 19
  • unfortunately this doesnt't work either... :( Again sometimes loses states of checked items, sometime break on line yourSelectedItems.remove((position)) inside setOnCheckedChangeListener() – Josef Sep 29 '13 at 11:32
0

You would be facing this prob if you have used getView in your listView.onItemSelectedListner The listView does not put every object in a different view thats why when you call getView(2) it will return the view of 2nd object of list on the screen not the view of second object of list... You have to implement it yourself using some boolean values or checkboxes in your class

Rehan
  • 3,270
  • 5
  • 31
  • 30
0

I think I get something... Instead of Chk.setOnCheckedChangeListener() I've changed to Chk.setOnClickListener(new OnClickListener()

public class SPCMjereAdapter extends BaseAdapter 
    {
        private Context context;


        public SPCMjereAdapter(Context c) 
        {           
            context = c;                    
        }

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

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }
        public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") );

            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));

            final CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);


            if(yourSelectedItems.contains((position))){
                Chk.setChecked(true);
             }else{
                Chk.setChecked(false);
             }

            Chk.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    if (Chk.isChecked())
                    {
                         yourSelectedItems.add(position);
                    } else
                    {
                        if(yourSelectedItems.contains(position)){                                               
                            yourSelectedItems.remove((position));                                   
                        }
                    }

                }
            });


            return convertView;
        }

 }

Now it works fine when scrolling up/down. But there is another problem and i'm little bit confused. When scrolling and randomly check/uncheck items program crashes and these errors I get:

FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
at java.util.ArrayList.remove(ArrayList.java:399)
at com.dem.spckontrola.SPCKontrola$SPCMjereAdapter$1.onClick(SPCKontrola.java:830)
at android.view.View.performClick(View.java:4084)
at android.widget.CompoundButton.performClick(CompoundButton.java:100)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method

)

Ok. I solved this by adding yourSelectedItems.remove(yourSelectedItems.indexOf(position));

So now the correct solution is:

 public class SPCMjereAdapter extends BaseAdapter 
    {
        private Context context;


        public SPCMjereAdapter(Context c) 
        {           
            context = c;                    
        }

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

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }
        public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") );

            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));

            final CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);


            if(yourSelectedItems.contains((position))){
                Chk.setChecked(true);
             }else{
                Chk.setChecked(false);
             }

            Chk.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    if (Chk.isChecked())
                    {
                         yourSelectedItems.add(position);
                    } else
                    {
                        if(yourSelectedItems.contains(position)){                                               
                            yourSelectedItems.remove(yourSelectedItems.indexOf(position));                                   
                        }
                    }

                }
            });


            return convertView;
        }

 }

But now I'm facing with new problem: How to get list of all checked and unchecked items where some checkboxes (items) are not visible due to many items in listview which are visible only when scrolling down?

Josef
  • 2,648
  • 5
  • 37
  • 73