ridoy
ridoy

Reputation: 6332

Wrong item selected on Listview onItemClick

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();                                
        }
    });

Upvotes: 0

Views: 1309

Answers (3)

Ercan
Ercan

Reputation: 3705

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
}

Upvotes: 0

Mohan Krishna
Mohan Krishna

Reputation: 362

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);

Upvotes: 1

Kaushik
Kaushik

Reputation: 6162

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());

         }
      });

Upvotes: 1

Related Questions