3

currently i am loading the images even if user not scrolled to view so when he will the image will be load faster from Picasso caching , on the list contractor

private void createImageCatch(ArrayList<Article> items) {
    for (int i = 0; i < items.size(); i++) {
            Article article = (Article) items.get(i);
            if (article.getImageUrl() != null
                    && article.getImageUrl().length() > 0)
                Picasso.with(mContext).load(article.getImageUrl())
                        .fetch();
    }
}

this is working perfect , the images are ready to go even if user scroll fast , but is this the best way to do this ?

IMPROVE UPDATE - added static boolean to make sure this method called only once , if images was added on server side this is not big deal for few images to be loaded on scroll time as long must of them already in cach.

Jesus Dimrix
  • 4,378
  • 4
  • 28
  • 62

2 Answers2

3

Have you considered using the Volley library? It has a special ImageView that downloads and caches images for you.

Replace the ImageView in your XML with something like this:

<com.android.volley.toolbox.NetworkImageView
    android:id="@+id/photo"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentTop="true"
    android:layout_marginRight="6dip"
 />

And load your image with

NetworkImageView photo = (NetworkImageView)view.findViewById(R.id.photo);
photo.setImageUrl("http://someurl.com/image.png", mImageLoader);

You do need to set up your ImageLoader, so create some fields:

private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;

and initialize them in your onCreate:

mRequestQueue = Volley.newRequestQueue(context);
mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
    private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(10);
    public void putBitmap(String url, Bitmap bitmap) {
        mCache.put(url, bitmap);
    }
    public Bitmap getBitmap(String url) {
        return mCache.get(url);
    }
});

Source: Setting up the Android Google Volley ImageLoader for NetworkImageView

Robin Kanters
  • 5,018
  • 2
  • 20
  • 36
  • but Picasso does it for me also so what is the different ? i have consider Glide also but the result will be the same if i understand current . i am thinking maybe to do my solution but only for images in position near the current position . if user in 10 position maybe i will get only next images instead all at once . i will update . – Jesus Dimrix Apr 21 '16 at 09:54
1

If you want to reuse ~30 small images, you can keep them in the memory as soft reference of Bitmaps, and recycle all after leaving Fragment or Activity with ListView.


For example your ImageView has size 55dp x 55dp, and there are 30 rows with images.


DisplayManager:

public static DP_55;//55 dp to px, do not count it each time, define it!
public static defineSize(Activity activity)
{
     DisplayMetrics metrics = new DisplayMetrics();
     activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
     DP_55 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 55, metrics);
}

Your Activity or Fragment:

public HashMap<String, SoftReference<Bitmap>> bitmaps = new HashMap<>();

Load images from File or Internet as Bitmap, scale to your size (55 dp) and put to the dictionary:

if (!bitmaps.containsKey(urlOrPath)) {
     //Load 'bitmap' and put to dictionary:
     bitmaps.put(urlOrPath, new SoftReference<>(
                Bitmap.createScaledBitmap(
                        bitmap,
                        DisplayManager.DP_55, DisplayManager.DP_55, true)));
}
else //Just reuse it!
     iv_image.setImageBitmap(bitmaps.get(urlOrPath).get());

How to recycle it:

Iterator<Map.Entry<String, SoftReference<Bitmap>>> iterator = bitmaps.entrySet().iterator();
while (iterator.hasNext()) {
       iterator.next().getValue().get().recycle();
       iterator.remove();
}

You won't get out of 40MB limit (if ImageView size is small and there are < 50 rows), and loading images after scrolling maximum fast.
Otherwise use ImageLoaders (Glide, Picasso, etc).

Community
  • 1
  • 1
Volodymyr Kulyk
  • 6,455
  • 3
  • 36
  • 63