I have a ListView
and a GridView
both causing me problems and OutOfMemory
errors when scrolling, I read online about the issue and saw this question so I used Sunil's first solution and implemented it in my code. the images for the GridView
and ListView
are at "/res/drawable/image1.png" and so on, I passed to the CustomAdapter
class this int array public static int[] mDrawableImg = {R.drawable.back, R.drawable.arrows, R.drawable.bomber, R.drawable.archers, R.drawable.knight};
and used this:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final Holder holder = new Holder();
final View rowView = inflater.inflate(R.layout.program_list2, null);
holder.img = (ImageView) rowView.findViewById(R.id.imageView1);
holder.img.setImageResource(imageId[position]);
// holder.img.setImageBitmap(convertBitmap(String.valueOf(imageId[position])));
return rowView;
}
Now as you see I added a line of code to load the image from Bitmap
with a function called convertBitmap
but my GridView
is empty, its scrollable meaning there are items but the images are not loaded.
convertBitmap
Function:
public static Bitmap convertBitmap(String path) {
Bitmap bitmap = null;
BitmapFactory.Options bfOptions = new BitmapFactory.Options();
bfOptions.inDither = false;
bfOptions.inTempStorage = new byte[32 * 1024];
File file = new File(path);
FileInputStream fs = null;
try {
fs = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (fs != null) {
bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fs != null) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
What have I done wrong and will it solve my OutOfMemory
errors? thanks.
The error you get is absolutely logical. Look at this line in your getView()
method:
final View rowView = inflater.inflate(R.layout.program_list2, null);
What does it mean? It means that you're creating a new instance of the item each time Android requests you a View
for it. That's pretty insane, because you just create and create more views while you scroll the ListView
(so is pretty natural that you get an out of memory error. And I'm sure your ListView
is scrolling laggy).
And I bet Android Studio is warning you this issue by remarking that line in yellow color.
Affortunately, you can fix it very easily. But let me say you some things. Look at the View
that you're receiving in the getView()
method as a parameter. Don't you see it? Is the variable that you called convertView
. And note that you're not using it. What is this View
? Is called a recycled view (Not to be confused with RecyclerView
class). Is a view that was previously inflated and no longer used because is not visible for the user. And this, my friend, this is the key of your problem and also of your solution: Instead of inflate one new view each time, just recycle it. I promise you is very simple. Now your getView
methos should look like this:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = inflater.inflate(R.layout.program_list2, null);
//final Holder holder = new Holder();
//holder.img = (ImageView) convertView.findViewById(R.id.imageView1);
//holder.img.setImageResource(imageId[position]);
ImageView img = (ImageView) convertView.findViewById(R.id.imageView1);
//Note you don't need the Holder
Bitmap imageBitmap = convertBitmap(imageId[position]);
if (imageBitmap != null)
img.setImageBitmap(imageBitmap);
else
img.setImageBitmap(null);
return convertView;
}
And please look at your usage of the ViewHolder pattern. You're using it wrong...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.