1

Here is how I have implemented bindView:

@Override
public void bindView(View view, Context context, Cursor cursor) 
{
    final ViewHolder holder = (ViewHolder) view.getTag();

    String name = (cursor.getString(cursor.getColumnIndexOrThrow("NotificationDateFor")));
    String image = cursor.getString(cursor.getColumnIndexOrThrow("imageUri"));

     System.out.println("cursor.getPosition(test): "+cursor.getPosition());

     holder.nametext.setText(name);
     // setImage(image, holder.iv); 

     holder.chk.setOnClickListener(new OnClickListener(){
         @Override
         public void onClick(View v) 
         {
             if (holder.chk.isChecked()) 
             {
                 itemChecked.set(cursor.getPosition(), true);
                 System.out.println("cursor.getPosition(true): "+cursor.getPosition());
             }
             else if (!holder.chk.isChecked()) 
             {
                 itemChecked.set(cursor.getPosition(), false);
                 System.out.println("cursor.getPosition(false): "+cursor.getPosition());
                 // AddDelete
             }  
         }              
     });

     holder.chk.setChecked(itemChecked.get(cursor.getPosition()));
} 

The problem occurs at itemChecked.set(cursor.getPosition(), true);

The description of the problem suggests me:

Cannot refer to a non-final variable cursor inside an inner class defined in a different method, change the modifier of Cursor to final.

However if I do final Cursor cursor, the position value inside the onClick does not get refreshed on scroll. I always get value of 5 if I do a System.out.println("cursor.getPosition(true): "+cursor.getPosition()); and my checkbox check gets messed up again.

Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
User3
  • 2,465
  • 8
  • 41
  • 84

2 Answers2

1

As error says... Inside the listener you cannot modify some variables, due it's inner class, so declare variables final:

public void bindView(View view, Context context, final Cursor cursor) {

If you need to modify cursor, use the values needed as final:

final int position = cursor.getPosition();
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
  • The downside is that my value does not get refreshed if I make it final. If I do a `System.out.println("cursor.getPosition(true): "+cursor.getPosition());` from within the onCLick listener I always get 5 – User3 Mar 23 '15 at 13:05
  • If so use the position, `final int position = cursor.getPosition();` and use it inside the listener to allow changes in Cursor. – Jordi Castilla Mar 23 '15 at 13:08
  • You just redefined sex! However it would be great if you explain how one works and the other does not. As far as I know final is just a means to let threads know that synchronization is needed to write a variable. Correct me if I am wrong? Then this is a design issue in BindView method because at many times I would require to get the position of the cursor within an onCLickListener. – User3 Mar 23 '15 at 13:12
  • final means you cannot change value, that's why is thread safe, but it can also useful for some other cases like this. This is a complex explanation, so you can check other answers like http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-differen – Jordi Castilla Mar 23 '15 at 13:14
1
    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        final ViewHolder holder = (ViewHolder) view.getTag();
        final int position = cursor.getPosition();

        String name = (cursor.getString(cursor.getColumnIndexOrThrow("NotificationDateFor")));
        String image = cursor.getString(cursor.getColumnIndexOrThrow("imageUri"));

         System.out.println("cursor.getPosition(test): "+position);

        holder.nametext.setText(name);
    //  setImage(image, holder.iv); 

        holder.chk.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {

                    if (holder.chk.isChecked()) {
                        itemChecked.set(position, true);
                       System.out.println("cursor.getPosition(true): "+position);
                    } else if (!holder.chk.isChecked()) {
                        itemChecked.set(position, false);
                        System.out.println("cursor.getPosition(false): "+position);
                        // AddDelete
                    }   
            }               
        });

        holder.chk.setChecked(itemChecked.get(position));

    } 
Andrei Tudor Diaconu
  • 2,157
  • 21
  • 26