2

I have a grid view which is populated using a custom ImageAdapter class extending BaseAdapter. The images are dynamically loaded from a particular folder in the SD card. I have named the images according to their postition (1.png, 2.png etc.). I have also set an OnClickListener for the grid items: an audio file with the same name as the image is played from the SD card.

It works well when the number of images is less and fits on a screen.

But when the number is large and the images doesn't fit on a screen, the next set of rows displayed by scrolling the screen downwards is mostly repetition of images from the first few rows rather than the images at the corresponding position.

I find from the logcat that the getView() function of the adapter class gets called initially only for the images which are visible on the screen and while scrolling downwards, its not being called properly for further positions

Also sometimes the entire set of images gets re-arranged. Should I do anything different from the basic implementation of grid view for properly displaying large number of images? Is there anything else I must be taking care of?

EDIT - CODE

I'm setting each tab using

tabGrid[i].setAdapter(new ImageAdapter(this,i));

This is the image adapter class

@Override
public int getCount() {
    // fileNames is a string array containing the image file names : 1.png, 2.png etc
    return fileNames.length;
}

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

@Override
public long getItemId(int position) {
    // I did not use this function
    return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
     View v;
     if(convertView==null) {
         LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         v = inflater.inflate(R.layout.grid_image, null);
         ImageView iv = (ImageView)v.findViewById(R.id.icon_image);
         String bitmapFileName = fileNames[position];
         Bitmap bmp =(Bitmap)BitmapFactory.decodeFile(dir.getPath() + "/" + bitmapFileName);a
         iv.setImageBitmap(bmp);
     }
     else {
     v = convertView;
     }
     return v;
}

Does the getItem() and getItemId() functions matter? The directories and file names are all valid.

2
  • Any chance you could post some code to see what could be going wrong ? :) Commented Jul 2, 2011 at 22:17
  • @Gregory : thanks for looking into it..i have added the code.. dint add the initially code because the qn became too lengthy Commented Jul 4, 2011 at 7:54

1 Answer 1

5

Here's a quick fix which should be better.

@Override
public String getItem(int position) {
    return fileNames[position];
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     View v;
     if(convertView==null) {
         LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         v = inflater.inflate(R.layout.grid_image, parent, false);
     }
     else {
        v = convertView;
     }

     ImageView iv = (ImageView)v.findViewById(R.id.icon_image);
     String bitmapFileName = getItem(position);
     Bitmap bmp =(Bitmap)BitmapFactory.decodeFile(dir.getPath() + "/" + bitmapFileName);a
     iv.setImageBitmap(bmp);

     return v;
}
  1. I filled getItem, it's not 100% needed but it's always better to have it. The rest of your adapter code can then rely on it
  2. The item id should be different for every entry, you could either use getItem(position).hashCode() (might be slower) or just return position (which I did here).
  3. The getView method is a bit more tricky. The idea is that if the convertView is null, you create it. And then, in every case, you set the view's content.
  4. The inflate in the getView item should use the parent as parent, and the "false" is there to tell the system not to add the new view to the parent (the gridview will take care of that). If you don't, some layout parameters might get ignored.

The erorr you had was because the views were getting recycled (convertView not null) and you weren't setting the content for those. Hope that helps !

Sign up to request clarification or add additional context in comments.

2 Comments

v = inflater.inflate(R.layout.grid_image, parent, false) made some pictures small but when i changed it to v = inflater.inflate(R.layout.grid_image, null) the images where properly displayed. @Gregory
@jerrin-george When using "parent, false", it'll use the layout_width (and height and anything starting with "layout_") to set the layout dimensions, whereas if you don't use, it probably falls back to "wrap_content", and won't try resizing the images. I would tend to think that you should keep the parent, false version and "fix" the layout, if that's possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.