Pedro Alves
Pedro Alves

Reputation: 1728

Repeatedly items when filling GridView with MediaStore imagers

I'm trying to load all images from sdcard's phone on a GridView. I implemented the code bellow but it is loading just a few photos and repeating it a hundred times. Don't have idea what i'm doing wrong!

This is the onCreate method:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_grid_images);

    //GridView
    imagesGridView = (GridView) findViewById(R.id.imagesGridView);

    //Do the query
    externalContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;        

    String[] projection = {MediaStore.Images.Media._ID}; 
    String selection = "";
    String [] selectionArgs = null;
    externalCursor = getContentResolver().query(externalContentUri,projection,selection,selectionArgs,null); 
    externalColumnIndex = externalCursor.getColumnIndex(MediaStore.Images.Media._ID);

    //Gets the adapter
    myAdapter = new ImageAdapter(this);
    imagesGridView.setAdapter(myAdapter);   
    imagesGridView.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            Toast.makeText(GridImages.this, "" + position, Toast.LENGTH_SHORT).show();
        }
    });

}

This is my custom adapter:

public class ImageAdapter extends BaseAdapter {
    private Context mContext;


    public ImageAdapter(Context c) {
        mContext = c;
    }

    public int getCount() {
        return externalCursor.getCount();
    }

    public Object getItem(int position) {
        return null;
    }

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

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
            externalCursor.moveToPosition(position);
            int imageID = externalCursor.getInt( externalColumnIndex );
            Uri uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,Integer.toString(imageID));

            imageView.setImageBitmap(loadThumbnailImage(uri.toString()));   

        } else {
            imageView = (ImageView) convertView;
        }


        return imageView;
    }

    protected Bitmap loadThumbnailImage( String url ) {
        // Get original image ID
        int originalImageId = Integer.parseInt(url.substring(url.lastIndexOf("/") + 1, url.length()));

        // Get (or create upon demand) the micro thumbnail for the original image.
        return MediaStore.Images.Thumbnails.getThumbnail(mContext.getContentResolver(),
                            originalImageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
    }

}

Upvotes: 0

Views: 1330

Answers (1)

user
user

Reputation: 87064

Your getView method should be:

   if (convertView == null) {  // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
    } else {
         imageView = (ImageView) convertView;
    }
    externalCursor.moveToPosition(position);
    int imageID = externalCursor.getInt( externalColumnIndex );
    Uri uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,Integer.toString(imageID))
    imageView.setImageBitmap(loadThumbnailImage(uri.toString()));   
    return imageView;
    }

With your current code you're setting the images only for the first time when GridView requires images(like when it first appears on the screen), for the other rows the old ones get recycled.

Upvotes: 1

Related Questions