1

I have a list adapter , and each item has a checkbox. I also have an option to delete from that list all the items the user checks. The part that should delete the selected items works well, but.. for example if I have

1. 0000
2. 5555
3. 9999

If I check 5555 and 9999, and click remove, they disappear but then 0000 gets checked even though I haven't pressed it.

(historyList is all the items in history fragment. listToRemove is only the checked items)

 @Override
public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) 
{ 
    View view = inflater.inflate( R.layout.fragment_history, container, false );
    adapter = new PasswordAdapter( historyList );
    setListAdapter(adapter);
    ImageView removeButton = ( ImageView ) view.findViewById( R.id.removeButton );
    removeButton.setOnClickListener( new OnClickListener(){
        @Override
        public void onClick( View v )
        {
            if ( !listToRemove.isEmpty() )
            {
                listToRemove.clear();

                adapter.updateList( historyList );
            }
        }
    });

    return view;
}
...
...
...
@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final View result;

        if (convertView == null) 
        {
            result = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_list_item, parent, false);
        } 
        else 
        {
            result = convertView;
        }

        final Password item = getItem( position );

        ( (TextView) result.findViewById( R.id.historyPasswordTextView) ).setText(item.getPasswordString());
        ( (TextView) result.findViewById( R.id.historyDateTextView ) ).setText(item.getPasswordString());
        CheckBox checkBoxToRemove = (CheckBox) result.findViewById( R.id.removePasswordFromHistoryCheckBox ) ;
        checkBoxToRemove.setOnCheckedChangeListener( new OnCheckedChangeListener(){
                @Override
                public void onCheckedChanged( CompoundButton buttonView, boolean isChecked )
                {
                    if( isChecked )
                    {
                        listToRemove.add( item );
                    //  Log.d( "TAG", listToRemove.toString() );

                        for( int i=0; i<listToRemove.size(); i++)
                            Log.d("TAG","checked after add: "+ listToRemove.get(i).getPasswordString());
                    }
                    else
                    {
                        listToRemove.remove( item );
                        for( int i=0; i<listToRemove.size(); i++)
                            Log.d("TAG","checked after remove: "+ listToRemove.get(i).getPasswordString());
                    }

                }
            });

Have I missed something?

BVtp
  • 2,308
  • 2
  • 29
  • 68

2 Answers2

1

Try like this maybe it works

     public View getView(int position, View convertView, ViewGroup parent) {
            final View result;
    ViewHolder holder;

            if (convertView == null) 
            {
    holder = new ViewHolder();
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_list_item, parent, false);

            holder. checkBoxToRemove = (CheckBox) convertView.findViewById( R.id.removePasswordFromHistoryCheckBox ) ;
    convertView.setTag(holder);
            } 
            else 
            {

    holder = (ViewHolder) convertView.getTag();
            }

            final Password item = getItem( position );


            holder .checkBoxToRemove.setOnCheckedChangeListener( new OnCheckedChangeListener(){
                    @Override
                    public void onCheckedChanged( CompoundButton buttonView, boolean isChecked )
                    {
                        if( isChecked )
                        {
                            listToRemove.add( item );
                        //  Log.d( "TAG", listToRemove.toString() );

                            for( int i=0; i<listToRemove.size(); i++)
                                Log.d("TAG","checked after add: "+ listToRemove.get(i).getPasswordString());
                        }
                        else
                        {
                            listToRemove.remove( item );
                            for( int i=0; i<listToRemove.size(); i++)
                                Log.d("TAG","checked after remove: "+ listToRemove.get(i).getPasswordString());
                        }

                    }
                });
return convertView;
}
     class ViewHolder {
            CheckBox checkBoxToRemove;
    }

And in your getView add this:

if(listToRemove.contains(item){
holder.checkBoxToRemove.setChecked(true);
}else{
holder.checkBoxToRemove.setChecked(false);
}
Amsheer
  • 7,046
  • 8
  • 47
  • 81
  • Thanks. I think there might be something wrong though.. It shows me some error.. and btw where do you return the result here for getView ? – BVtp Jul 15 '15 at 12:56
  • I copy your code and edit. Check my edited answe now – Amsheer Jul 15 '15 at 13:02
  • Did you add this class ViewHolder { CheckBox checkBoxToRemove; } in your adapter class – Amsheer Jul 15 '15 at 13:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/83329/discussion-between-amsheer-and-bvtp). – Amsheer Jul 15 '15 at 13:04
  • have a look at this http://stackoverflow.com/questions/18605768/how-to-create-custom-contact-list-with-checkbox – karan Jul 15 '15 at 13:05
0

I think you should not use checkbox inside a ListView. You problem may be due to the fact that the row view are reused. I mean that the checkbox can be from a previous visible row (in your example for the row 0000 after deleting, the checkbox can be the one of the row 5555 before deleting).

I think the best way to do that is to use onItemClickListener. In your onItemClick method you add or remove item from the listToRemove of your adapter and call adapter.notifyDataSetChange().

And in your getView method you draw the row according to the listToRemove list.

sonic
  • 1,894
  • 1
  • 18
  • 22
  • what should I replace the checkbox with? – BVtp Jul 15 '15 at 12:58
  • you can leave the checkbox but disable user interaction on it. Or use an image view with two drawable for selected and not selected. My point is to not use `OnCheckedChangeListener` to handle line selection. – sonic Jul 15 '15 at 13:04
  • You could also try a CheckedTextView or a custom view that implements Checkable. Then your adapter can manage rechecking the appropriate rows based on a list of checked indexes that you maintain and update when an item's checked state has changed. – HBG Jul 15 '15 at 13:23