Randy
Randy

Reputation: 1

Repeated ImageView on ListView

My ImageView keep repeated on ListView every 6 items here my code for CustomAdapter

public class NewsAdapter extends ArrayAdapter<NewsContainer> {

private Context context;
private NewsContainer[] newsContainer;

public NewsAdapter(Context context, int textViewResourceID, NewsContainer[] newsContainers) {
    super(context, textViewResourceID, newsContainers);
    this.newsContainer = newsContainers;
    this.context = context;
}

@Override
public long getItemId(int position){
    return position;
}

public View getView(int position, View view, ViewGroup parent){
    viewHolder holder = null;
    if(view == null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.news_listview, null);

        holder = new viewHolder();
        holder.image = (ImageView) view.findViewById(R.id.thumbnail);
        holder.title = (TextView) view.findViewById(R.id.title);
        holder.created_date = (TextView) view.findViewById(R.id.created_date);
        holder.category = (TextView) view.findViewById(R.id.category);
        holder.post_count = (TextView) view.findViewById(R.id.post_count);
        view.setTag(holder);
    } else {
        holder = (viewHolder) view.getTag();
    }

    NewsContainer news = newsContainer[position];
    SimpleDateFormat format = new SimpleDateFormat("DD/MM/yyyy", Locale.US);
    if(news != null){
        String date = format.format(news.getCreatedDate());
        holder.title.setText(news.getTitle());
        holder.post_count.setText(String.valueOf(news.getPostCount()));
        holder.created_date.setText(date);
        holder.category.setText(Html.fromHtml(news.getCategory()));
        if(!news.getThumbnail().equals("empty")){
            new ImageDownloaderTask(holder.image).execute(news.getThumbnail());
        }    
    }

    return view;
}

static class viewHolder {
    ImageView image;
    TextView title;
    TextView created_date;
    TextView category;
    TextView post_count;
}

ImageDownloader class

public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {

private final WeakReference<ImageView> imageViewWeakReference;

public ImageDownloaderTask(ImageView imageView) {
    this.imageViewWeakReference = new WeakReference<ImageView>(imageView);
}

@Override
protected Bitmap doInBackground(String... params) {
    return downloadBitmap(params[0]);
}

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

    if(imageViewWeakReference != null){
        ImageView imageView = imageViewWeakReference.get();
        if(imageView != null){
            if(bitmap != null){
                imageView.setImageBitmap(bitmap);
            } else {
                imageView.setImageDrawable(imageView.getContext().getResources().getDrawable(R.drawable.ic_loading_image));
            }
        }
    }
}

@TargetApi(Build.VERSION_CODES.FROYO)
static Bitmap downloadBitmap(String url) {
    final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
    final HttpGet getRequest = new HttpGet(url);
    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            Log.w("ImageDownloader", "Error " + statusCode
                    + " while retrieving bitmap from " + url);
            return null;
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent();
                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                entity.consumeContent();
            }
        }
    } catch (Exception e) {
        // Could provide a more explicit error message for IOException or
        // IllegalStateException
        getRequest.abort();
        Log.w("ImageDownloader", "Error while retrieving bitmap from " + url);
    } finally {
        if (client != null) {
            client.close();
        }
    }
    return null;
}

I have tried using ViewHolder but the ImageView keeps repeat, and found that the ListView recycles its view in order to keep the memory occupation low. but i can't understand how to solve this problem.

Upvotes: 0

Views: 1390

Answers (3)

Avinash_ks
Avinash_ks

Reputation: 173

public View getView(int position, View view, ViewGroup parent){

 if(view == null){
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      view = inflater.inflate(R.layout.news_listview, null);
  }

    ImageView image = (ImageView) view.findViewById(R.id.thumbnail);
    TextView  title = (TextView) view.findViewById(R.id.title);
    TextView  created_date = (TextView) view.findViewById(R.id.created_date);
    TextView category = (TextView) view.findViewById(R.id.category);
    TextView post_count = (TextView) view.findViewById(R.id.post_count);

 NewsContainer news = NewsContainer[position];
 SimpleDateFormat format = new SimpleDateFormat("DD/MM/yyyy", Locale.US);
 if(news != null){
     String date = format.format(news.getCreatedDate());
     title.setText(news.getTitle());
     post_count.setText(String.valueOf(news.getPostCount()));
     created_date.setText(date);
     category.setText(Html.fromHtml(news.getCategory()));
     if(!news.getThumbnail().equals("empty")){
        new ImageDownloaderTask(image).execute(news.getThumbnail());
  }    

}

Upvotes: 0

Shakti
Shakti

Reputation: 1581

else {
    holder = (viewHolder) view.getTag();
}

Here is your real problem, you are inflating in case view is null but not doing any modifications in case it already has a value. When the view is being recycled it will contain some value and won't be null. So you have to change all the values instead of reusing the existing ones.

Upvotes: 3

Ken
Ken

Reputation: 31161

You should clear or reset the image view if you get an empty thumbnail in getView.

Writing from my phone, apologies for the brevity.

Edit: I don't see that you've set this in your code at all. Where you have for instance:

if(news != null){
    String date = format.format(news.getCreatedDate());
    holder.title.setText(news.getTitle());
    holder.post_count.setText(String.valueOf(news.getPostCount()));
    holder.created_date.setText(date);
    holder.category.setText(Html.fromHtml(news.getCategory()));
    if(!news.getThumbnail().equals("empty")){
        new ImageDownloaderTask(holder.image).execute(news.getThumbnail());
    }    
}

what if news is null or news.getThumbnail().equals("empty") == true? You will be leaving a recycled image view unchanged.

Upvotes: 2

Related Questions