0

Facing a very weird issue. I have a listview with checkbox on every item, when i click on the first item of the listview it is being selected, but along with this item, the last item of the listview is also being selected! when i scroll the listview. Without scroll it works perfect.

Also when i am selecting the last item, first item is being selected along with it after scrolling. Remind, all other items between these first and last are working correctly. And the funny part is, after selecting the first or last item, if i don't scroll the listview for 2-3 seconds it works perfectly then.So i am expecting this may be a problem of view rendering or somewhat. Can somebody point me what the hell is going on here..

Cursor cursor = queryDatabase();

    // The desired columns to be bound
      String[] columns = new String[] {               
        DataBaseHelper.ROW_PROFILE_NAME,
        DataBaseHelper.ROW_PROFILE_TYPE,
        DataBaseHelper.ROW_ID
      };

      // the XML defined views which the data will be bound to
      int[] to = new int[] { 
        R.id.profileName,
        R.id.profileStatus
      };

      // create the adapter using the cursor pointing to the desired data 
      //as well as the layout information
      mAdapter = new SimpleCursorAdapter(
        this, R.layout.profile_listview_delete_item, 
        cursor, 
        columns, 
        to,
        0);

      listView = (ListView) findViewById(R.id.profile_listview_delete_main);
      // Assign adapter to ListView
      listView.setAdapter(mAdapter);

      listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
            // TODO Auto-generated method stub

            CheckBox cb;                

            Cursor c = mAdapter.getCursor();
            String prodile_id = c.getString(c.getColumnIndex(DataBaseHelper.ROW_ID));

            cb = (CheckBox)arg1.findViewById(R.id.checkbox);
            cb.toggle();

            if(cb.isChecked())
            {                   
                profileStack.add(prodile_id);                   
                //Toast.makeText(getApplicationContext(), String.valueOf(profileStack), Toast.LENGTH_LONG).show();                  
                counter++;              
            }
            else if(!cb.isChecked())
            {
                profileStack.remove(prodile_id);                    
                //Toast.makeText(getApplicationContext(), String.valueOf(profileStack), Toast.LENGTH_LONG).show();                  
                counter--;                  
            }               
            countSelectedItem.setText(String.valueOf(counter)+" items selected");

            mAdapter.notifyDataSetChanged();                                
        }
    });
ridoy
  • 6,274
  • 2
  • 29
  • 60
  • Can you Please post your Adapter Class I Think this is problem of View Holder Pattern? – Rajesh Jadav Sep 29 '14 at 05:20
  • @Rajesh,i am using SimpleCursorAdapter as you can see the code above. – ridoy Sep 29 '14 at 05:21
  • Your way of code is wrong. You have to use custom adapter with viewholder class, From that adapter while change the value of your checkbox you have to change value of a field from your adapter regards this checkbox. After while clicking listview get the position and get the values from your adapter. – Gunaseelan Sep 29 '14 at 05:21
  • Check : http://stackoverflow.com/questions/25844210/how-to-select-multiple-items-in-a-listview-populated-from-arraylist-in-android/25844671#25844671. – Haresh Chhelana Sep 29 '14 at 05:22
  • possible duplicate of [Android listview duplicates the item on scroll](http://stackoverflow.com/questions/8398529/android-listview-duplicates-the-item-on-scroll) – Shruti Sep 29 '14 at 05:27
  • @Shruti, that is not the duplicate that you mentioned. Do you check my code? i used notifyDataSetChanged() there. – ridoy Sep 29 '14 at 05:31

3 Answers3

1

You should use a custom Adapter (and a model class it is optional. Here TemaRescatado is a model class in snippet) for that. In getView(...) you have to use CompoundButton.OnCheckedChangeListener try to use ViewHolder pattern

code snippet

viewHolder.checkbox = (CheckBox) view.findViewById(R.id.checkBox1);
viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

      @Override
      public void onCheckedChanged(CompoundButton buttonView,
         boolean isChecked) {
         TemaRescatado element = (TemaRescatado) viewHolder.checkbox
                  .getTag();
         element.setSelected(buttonView.isChecked());

         }
      });
Kaushik
  • 6,150
  • 5
  • 39
  • 54
  • Isn't it possible to correct the problem with current code? Because i told all other items are working good. – ridoy Sep 29 '14 at 05:29
  • 2
    I'm not sure but, it is not possible it is better to custom adapter because it will optimize your code and implementing `ViewHolder` pattern `ListView's` scroll will be *smooth* – Kaushik Sep 29 '14 at 05:33
  • u can try with `mAdapter.notifyDataSetInvalidated()` after `notifyDataSetChanged()`. – Kaushik Sep 29 '14 at 05:38
  • as @kaushik suggested...use viewholder else you will get undesired result – kgandroid Sep 29 '14 at 05:42
  • @kaushik, notifyDataSetInvalidated() not works either, i know possibly ViewHolder may solve this problem, but it will be a long task to change the code of an end app! – ridoy Sep 29 '14 at 05:46
  • @ridoy : just follow that tutorial and you just need hardly half an hour to implement it – Kaushik Sep 29 '14 at 06:02
1

You should get the cursor from AdapterView which is passed as argument to the onItemClick method.

Change the code.

Cursor c = mAdapter.getCursor();

to

Cursor c = (Cursor) arg0.getItemAtPosition(position);
Mohan Krishna
  • 352
  • 3
  • 15
  • Nope, it not changes the situation. – ridoy Sep 29 '14 at 05:50
  • Updated my answer check this and let me know it si working ot not. – Mohan Krishna Sep 29 '14 at 06:02
  • nope it is not working. Still the same thing, check 1st item and then scroll through, seen the last item also selected! But check 1st item, wait 2 seconds, scroll through and then seen it works good! weird! – ridoy Sep 29 '14 at 06:16
0

This issue happens because ListView's recycling. It re uses the first visible Views as soon as it is not visible to show next data of the adapter.Therefore when you check and checkbox with respect to a data in the List's position. it will remain same as you left it. So My solution to this issue is :

in your adapter's getView()

put a simple if-else statement to check if the checkbox should be checked or not like this:

// note that this is a pseudo code
if(ID exist in profileStack){
//set checkBox
}
else{
//set checkBox
}
Ercan
  • 3,705
  • 1
  • 22
  • 37