I have created an custom ListView
in which i display image as an list Item. The image i display as a list item is stored in my InternalStorage
of the device, What i notice is when number of item is more then seven the list view scroll become slow and the items in the ListView
jerk while scrolling. Is anything wrong in my code, or miss something to do in my code. Please help me to solve this out.
Code for displaying List View item
public class ListViewAdapter extends BaseAdapter
{
private Activity activity;
private ArrayList<String> fileNameArray;
private LayoutInflater inflater=null;
public ImageLoader imageLoader;
public ListViewAdapter(Activity a, ArrayList<String> d)
{
activity = a;
fileNameArray = d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount()
{
return fileNameArray.size();
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
public class ViewHolder
{
ImageView image;
}
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if(convertView == null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.page_list_item, null);
holder.image = (ImageView)convertView.findViewById(R.id.image);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
// Load image from internalstoarage and display in image view
imageLoader.DisplayImage(m_DirectoryPath.getPath() + "/" + fileNameArray.get(position), holder.image, true);
return convertView;
}
}
Code for image loader class
public class ImageLoader
{
MemoryCache memoryCache = new MemoryCache();
private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
Context m_context;
public ImageLoader(Context context)
{
m_context = context;
executorService = Executors.newFixedThreadPool(5);
}
public void DisplayImage(String url, ImageView imageView, boolean useCachedImage)
{
imageViews.put(imageView, url);
Bitmap bitmap = memoryCache.get(url);
if(bitmap!=null && useCachedImage)
{
imageView.setImageBitmap(bitmap);
}
else
{
queuePhoto(url, imageView);
}
}
private void queuePhoto(String url, ImageView imageView)
{
PhotoToLoad p = new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private Bitmap getBitmap(String url)
{
File filePath = new File(url);
// from internal storage cache
Bitmap b = decodeFile(filePath);
if (b != null)
{
return b;
}
return null;
}
// decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File filePath)
{
try
{
// decode image size
int Required_Height = 0;
BitmapFactory.Options option = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(filePath), null, option);
WindowManager wm = (WindowManager) m_context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(display.getWidth() == 480)
{
Required_Height = 150;
}
else if(display.getWidth() == 800)
{
Required_Height = 200;
}
bitmap = Bitmap.createBitmap(bitmap, 0, 0, option.outWidth, Required_Height);
return bitmap;
}
catch (FileNotFoundException e){
}
return null;
}
// Task for the queue
private class PhotoToLoad
{
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i)
{
url = u;
imageView=i;
}
}
class PhotosLoader implements Runnable
{
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad)
{
this.photoToLoad = photoToLoad;
}
@Override
public void run()
{
if(imageViewReused(photoToLoad))
return;
Bitmap bmp = getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if(imageViewReused(photoToLoad))
return;
BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
Activity a = (Activity)photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
}
}
boolean imageViewReused(PhotoToLoad photoToLoad)
{
String tag = imageViews.get(photoToLoad.imageView);
if(tag == null || !tag.equals(photoToLoad.url))
return true;
return false;
}
// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable
{
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
public void run()
{
if(imageViewReused(photoToLoad))
return;
if(bitmap != null)
photoToLoad.imageView.setImageBitmap(bitmap);
}
}
public void clearCache()
{
memoryCache.clear();
}
}