0

I am tying to lazy load images into my ListView, the images are loading fine, but I've a problem. While loading the images get interchanged.

Let's say that the ListView has 10 rows. It loads the images for 1st row, it displays it in the 1st row, then it loads the image for the 2nd row. It displays in the 2nd row for a moment and then it displays the image for the 2nd row in the 1st row. Then the ImageView in row1 switches between images of 1st row and 2nd. Similarly while loading images of next rows. the previous row's images get switched between. And then after loading all the images, everything gets displayed correctly.

Here's my code

Adapater class:

public class FamilyMemberListAdapter extends ArrayAdapter<Map<String, String>> {
    List<Map<String, String>> familyMemberList = new ArrayList<Map<String, String>>();
    private Activity activity;

    public FamilyMemberListAdapter(Activity activity,
            List<Map<String, String>> familyMemberList) {
        super(activity, R.layout.activity_gch_family_members, familyMemberList);
        this.activity = activity;
        this.familyMemberList = familyMemberList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(this.getContext()).inflate(
                    R.layout.activity_gch_family_member_item, parent, false);
            holder = new ViewHolder();
            holder.lblFamilyMemberName = (TextView) convertView
                    .findViewById(R.id.lblFamilyMemberItem);
            holder.lblFamilyMemberRelation = (TextView) convertView
                    .findViewById(R.id.lblFamilyMemberRelationItem);
            holder.imgProfilePic = (ImageView) convertView
                    .findViewById(R.id.imgvProfilePic);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        int accountId = Integer.valueOf(familyMemberList.get(position).get(
                "accountId"));
        holder.lblFamilyMemberName.setText("Name: "
                + familyMemberList.get(position).get("name"));
        holder.lblFamilyMemberRelation.setText("Relation: "
                + familyMemberList.get(position).get("relation"));
        if (holder.imgProfilePic != null) {
            new ImageDownloaderTask(holder.imgProfilePic).execute(String
                    .valueOf(accountId));
        }
        return convertView;
    }

    @Override
    public int getCount() {
        return familyMemberList.size();
    }

    static class ViewHolder {
        TextView lblFamilyMemberName;
        TextView lblFamilyMemberRelation;
        ImageView imgProfilePic;
    }
}

Imageloader AsyncTask:

public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;

    public ImageDownloaderTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        String responseText = null;
        HttpClient httpClient = ServiceHelper.getHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpGet httpGet = new HttpGet(RestApiPaths.GET_PROFILE_PIC + accountId);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            final HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream inputStream = null;
                try {
                    // getting contents from the stream
                    inputStream = entity.getContent();

                    // decoding stream data back into image Bitmap that android understands
                    final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                    return bitmap;
                 } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    entity.consumeContent();
                }
            }
            Log.d(TAG, responseText);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null) {
            ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                if (bitmap != null) {
                    imageView.setImageBitmap(bitmap);
                } else {
                    Drawable placeholder = imageView.getContext().getResources().getDrawable(R.drawable.holder_pic_side);
                    imageView.setImageDrawable(placeholder);
                }
            }
        }
    }
}

I've created a Static class for the ListView items. Still Why is the images go on interchanging while loading. Please tell me what I'm doing wrong here.

2
  • 1
    Try with holder.imgProfilePic.setTag(accountId); before you call the AsyncTask. Add an extra parameter accountId to your task. Then in onPostExecute check if it is the same accountId as in the image view. Commented Apr 26, 2016 at 14:12
  • that solved my problem, thanks a lot Commented Apr 27, 2016 at 5:43

2 Answers 2

1

Add holder.imgProfilePic.setTag(accountId); before you call the AsyncTask. Add an extra parameter accountId to your task. Then in onPostExecute check if it is the same accountId as in the image view

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

Comments

0

Maybe try to use libraries like picasso or universal image loader or something. They have solved most of problems with image loading

2 Comments

This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you need to gain reputation before you can comment on others’ posts to prevent abuse; why don’t you try and get some by answering a question?
That was the first thing I tried. But the images that I want to load require session.

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.