7

I'm using Glide library for loading images from URL, which I get from Graph Request (Facebook). It's used in RecyclerAdapter. When I'm scrolling, each ImageView shows wrong picture for about less than one second, then correct one. Here is the code:

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

    ImageView main_image = viewHolder.main_image,

    getEventCover(position, main_image);

        }

private void getEventCover(int position, final ImageView img){

        GraphRequest request = GraphRequest.newGraphPathRequest(
                AccessToken.getCurrentAccessToken(),
                event.get(position).getEventID(),
                new GraphRequest.Callback() {
                    @Override
                    public void onCompleted(GraphResponse response) {

                        JSONObject data = response.getJSONObject();

                        try {
                            JSONObject cover = data.getJSONObject("cover");
                            String source = cover.getString("source");

                            Glide.with(fragment)
                                    .load(source)
                                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                                    .centerCrop()
                                    .into(img);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
        );

        Bundle parameters = new Bundle();
        parameters.putString("fields", "cover");
        request.setParameters(parameters);
        request.executeAsync();
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Panczur
  • 633
  • 1
  • 9
  • 26
  • Glide loads images asynchronously. If you have default image in your layout, It'll be showed at first and then load the right one. If is your case, try removing the default image in layout or replace it for another one – Rene Limon Jul 07 '16 at 16:54
  • 1
    Thanks for response, but i don't have set default image in layout – Panczur Jul 07 '16 at 16:56

2 Answers2

8

Your "problem" is that the ImageViews you are using are recycled from previous rows (which are disappearing while scrolling). Thus your ImageView in onBindViewHolder already contains a previous image.

This image is displayed until the network requests (GraphRequest and Glide) for the new image are finished.

To avoid the problem you have to clear your ImageView before calling getEventCover. This can be done by setting an placeholder image or by setting a transparent image as follows:

main_image.setImageResource(android.R.color.transparent);
dthulke
  • 949
  • 9
  • 23
  • 3
    This isn't sufficient. You must also call Glide.clear before calling setImageResource. Otherwise in rare cases you will see a random previous request complete before your new requests completes. Normally this isn't necessary because into() will do the same thing, but in this case you're calling into asynchronously, so you still need to synchronously call clear – Sam Judd Aug 01 '16 at 00:05
  • 1
    @SamJudd brother you are right but even what you say is also not working i mean the library is so fast a loading images that it loads 3-4 random images before it shows the real one – Harkal Aug 17 '18 at 05:32
4
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

    ImageView main_image = viewHolder.main_image,
    main_image.setImageURI(null);
    getEventCover(position, main_image);

        }

During the process of (binding) preparing a child view to display data, a (recycled) view previously used to display data is being retrieved from the cache for reuse. As this process skips initial layout inflation and construction, the ImageView noticeably retains it's source. Setting the source to null immediately drastically improves performance.

apelsoczi
  • 1,102
  • 8
  • 11