Custom GridView with ArrayAdapter out of sync with backing data
<p>im developing a gridview program. In this program im displaying some images when i click that one images it will be highlighted. its working fine but my problem is when im scrolling down the unselected image also was highlighted..</p>

<p>here is my code..</p>

<pre><code>package com.SdcardIma;


import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

/**
 * Loads images from SD card. 
 * 
 * @author Mihai Fonoage
 *
 */
public class SdcardIma extends Activity implements
OnItemClickListener {

/**
 * Grid view holding the images.
 */
private List&lt;String&gt; pathlist=new ArrayList&lt;String&gt;();

private List&lt;Object&gt; viewList=new ArrayList&lt;Object&gt;();
private List&lt;Integer&gt; checkList=new ArrayList&lt;Integer&gt;();
private int count =0;
private GridView sdcardImages;
//  private boolean isVisble = false;
/**
 * Image adapter for the grid view.
 */
private ImageAdapter imageAdapter;
/**
 * Display used for getting the width of the screen. 
 */
private Display display;

/**
 * Creates the content view, sets up the grid, the adapter, and the click listener.
 * 
 * @see android.app.Activity#onCreate(android.os.Bundle)
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);        
    // Request progress bar
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    setContentView(R.layout.main);

    display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

    setupViews();
    setProgressBarIndeterminateVisibility(true); 
    loadImages();
}

/**
 * Free up bitmap related resources.
 */
protected void onDestroy() {
    super.onDestroy();
    final GridView grid = sdcardImages;
    final int count = grid.getChildCount();
    ImageView v = null;
    for (int i = 0; i &lt; count; i++) {
        v = (ImageView) grid.getChildAt(i);
        ((BitmapDrawable) v.getDrawable()).setCallback(null);
    }
}
/**
 * Setup the grid view.
 */
private void setupViews() {
    sdcardImages = (GridView) findViewById(R.id.sdcard);
    sdcardImages.setNumColumns(display.getWidth()/95);
    sdcardImages.setClipToPadding(false);
    sdcardImages.setOnItemClickListener(SdcardIma.this);
    imageAdapter = new ImageAdapter(getApplicationContext()); 
    sdcardImages.setAdapter(imageAdapter);
}
/**
 * Load images.
 */
private void loadImages() {
    final Object data = getLastNonConfigurationInstance();
    if (data == null) {
        new LoadImagesFromSDCard().execute();
    } else {
        final LoadedImage[] photos = (LoadedImage[]) data;
        if (photos.length == 0) {
            new LoadImagesFromSDCard().execute();
        }
        for (LoadedImage photo : photos) {
            addImage(photo);
        }
    }
}
/**
 * Add image(s) to the grid view adapter.
 * 
 * @param value Array of LoadedImages references
 */
private void addImage(LoadedImage... value) {
    for (LoadedImage image : value) {
        imageAdapter.addPhoto(image);
        imageAdapter.notifyDataSetChanged();
    }
}

/**
 * Save bitmap images into a list and return that list. 
 * 
 * @see android.app.Activity#onRetainNonConfigurationInstance()
 */
@Override
public Object onRetainNonConfigurationInstance() {
    final GridView grid = sdcardImages;
    final int count = grid.getChildCount();
    final LoadedImage[] list = new LoadedImage[count];

    for (int i = 0; i &lt; count; i++) {
        final ImageView v = (ImageView) grid.getChildAt(i);
        list[i] = new LoadedImage(((BitmapDrawable) v.getDrawable()).getBitmap());
    }

    return list;
}
/**
 * Async task for loading the images from the SD card. 
 * 
 * @author Mihai Fonoage
 *
 */
class LoadImagesFromSDCard extends AsyncTask&lt;Object, LoadedImage, Object&gt; {

    /**
     * Load images from SD Card in the background, and display each image on the screen. 
     *  
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected Object doInBackground(Object... params) {
        //setProgressBarIndeterminateVisibility(true); 
        Bitmap bitmap = null;
        Bitmap newBitmap = null;

        String[] projection = {android.provider.MediaStore.Images.Media._ID};

        System.out.println("the value of projection=&gt;"+projection);
        // Create the cursor pointing to the SDCard
        Cursor  cursor = managedQuery( android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection, // Which columns to return
                null,       // Return all rows
                null,
                android.provider.MediaStore.Images.Thumbnails._ID);

        String[] projection1 = {android.provider.MediaStore.Images.Media.DATA};

        cursor = managedQuery( android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection1, // Which columns to return
                null,       // Return all rows
                null,
                null);

        int columnIndex = cursor.getColumnIndexOrThrow(android.provider.MediaStore.Images.Media.DATA);
        int size = cursor.getCount();
        // If size is 0, there are no images on the SD Card.
        if (size == 0) {
            //No Images available, post some message to the user
        }

        cursor.moveToFirst();
        while (cursor.isAfterLast() == false) {
            //view.append("n" + mCursor.getString(1));
              String imagePath = cursor.getString(columnIndex);
              System.out.println("gridview image path values===="+imagePath);
               bitmap = BitmapFactory.decodeFile(imagePath);
              if (bitmap != null) {
                  newBitmap = Bitmap.createScaledBitmap(bitmap, 70, 70, true);
                  bitmap.recycle();
                  if (newBitmap != null) {
                      publishProgress(new LoadedImage(newBitmap));
                  }
              }
            cursor.moveToNext();
        }
        cursor.close();
        return null;
    }
    /**
     * Add a new LoadedImage in the images grid.
     *
     * @param value The image.
     */
    @Override
    public void onProgressUpdate(LoadedImage... value) {
        addImage(value);
    }
    /**
     * Set the visibility of the progress bar to false.
     * 
     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
     */
    @Override
    protected void onPostExecute(Object result) {
        setProgressBarIndeterminateVisibility(false);
    }
}

/**
 * Adapter for our image files. 
 * 
 * @author Mihai Fonoage
 *
 */
class ImageAdapter extends BaseAdapter {

    private Context mContext; 
    private LayoutInflater inflater=null;
    private ArrayList&lt;LoadedImage&gt; photos = new ArrayList&lt;LoadedImage&gt;();

    public ImageAdapter(Context context) { 
        mContext = context; 
        inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    } 

    public void addPhoto(LoadedImage photo) { 
        photos.add(photo); 
    } 

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

    public Object getItem(int position) { 

        return photos.get(position); 
    } 

    public long getItemId(int position) { 
        return position; 
    } 

    public class  ViewHolder{
        public ImageView back_Frame_Off;
        public ImageView back_Frame_On;
        public ImageView pictureImage;
        public RelativeLayout rel;
        public boolean isVisble = false;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        ViewHolder viewHolder;

        if(convertView==null){
            view = inflater.inflate(R.layout.view, null);
            viewHolder=new ViewHolder();
            viewHolder.rel=(RelativeLayout)view.findViewById(R.id.frameLayout1);
            viewHolder.rel.setLayoutParams(new GridView.LayoutParams(63,  63));

            viewHolder.back_Frame_On=(ImageView)view.findViewById(R.id.imageView2);
            viewHolder.back_Frame_On.setMaxHeight(55);
            viewHolder.back_Frame_On.setMaxWidth(55);
            viewHolder.back_Frame_On.setPadding(8, 8, 0, 0);

            viewHolder.pictureImage=(ImageView)view.findViewById(R.id.imageView3);
            viewHolder.pictureImage.setMaxHeight(53);
            viewHolder.pictureImage.setMaxWidth(53);
            viewHolder.pictureImage.setPadding(10, 10, 0, 0);
            view.setTag(viewHolder);
            /*view.setId(count);
            count++;*/
        }
        else
            viewHolder=(ViewHolder)view.getTag();

        viewHolder.back_Frame_Off=(ImageView)view.findViewById(R.id.imageView1);
        viewHolder.back_Frame_Off.setMaxHeight(63);
        viewHolder.back_Frame_Off.setMaxWidth(63);

        viewHolder.back_Frame_Off.setImageResource(R.drawable.photoview_frame_on);
        viewHolder.back_Frame_On.setImageResource(R.drawable.photoview_frame_off);

        viewHolder.pictureImage.setScaleType(ImageView.ScaleType.FIT_CENTER);
        viewHolder.pictureImage.setPadding(8, 8, 8, 8);
        viewHolder.pictureImage.setImageBitmap(photos.get(position).getBitmap());

            return view;
        }   
}

/**
 * A LoadedImage contains the Bitmap loaded for the image.
 */
private static class LoadedImage {
    Bitmap mBitmap;

    LoadedImage(Bitmap bitmap) {
        mBitmap = bitmap;
    }

    public Bitmap getBitmap() {
        return mBitmap;
    }
}
/**
 * When an image is clicked, load that image as a puzzle. 
 */
public void onItemClick(AdapterView&lt;?&gt; parent, View v, int position, long id) {        

     int columnIndex = 0;
    String[] projection = {android.provider.MediaStore.Images.Media.DATA};
        Cursor cursor = managedQuery( android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection, // Which columns to return
                null,       // Return all rows
                null,
                null);
        columnIndex = cursor.getColumnIndexOrThrow(android.provider.MediaStore.Images.Media.DATA);
        cursor.moveToPosition(position);


        System.out.println("gridview selectedd postion valie===="+viewList.size());
        // Get image filename
        String imagePath = cursor.getString(columnIndex);

        System.out.println("gridview seleccted path valie===="+imagePath);

        Toast.makeText(SdcardIma.this, "Please select photos"+position, Toast.LENGTH_SHORT).show();

       View frame= sdcardImages.getChildAt(position);

       if(((ViewGroup) frame).getChildCount() != 3 )
        {
        ImageView backImageFrame1 =(ImageView)((ViewGroup) frame).getChildAt(0);
            backImageFrame1.setVisibility(View.GONE);
               for(int i=0;i&lt;((ViewGroup) frame).getChildCount();i++){
                   View vTemp = ((ViewGroup) frame).getChildAt(i);
                   if(vTemp instanceof TickImage)
                   {
                       ((ViewGroup) frame).removeViewAt(i);
                   }
               }
            for(int i=0;i&lt;pathlist.size();i++)
            {
                String val=pathlist.get(i);
                if( val.equals(imagePath))
                {
                pathlist.remove(imagePath);
                }
            } 
        }
        else
        {
             TickImage tickImage=new TickImage(SdcardIma.this);
            //tickImage.tagValue=position;

            ImageView backImageFrame1 =(ImageView)((ViewGroup) frame).getChildAt(0);
                backImageFrame1.setVisibility(View.VISIBLE);

                ((ViewGroup) frame).addView(tickImage, 25, 25); 
               pathlist.add(imagePath);
        }
    }


}
</code></pre>

<p>in this program i use another class for adding ticked image to that clicked gridview child view..... if anyone know it how to solve this problem pls help me. as soon as possible... </p>

<p>advance thanks</p>
