Search code examples
androidlistviewuniversal-image-loader

Android ListView repeat image


I'm implementing a listview on android that contains an imageview and I'm experiencing a problem: When a row does not have an image it is repeating an image of the previous item.

Here's my adapter:

    public class NewsAdapter extends BaseAdapter {
        private final LayoutInflater inflater;
        private final Context context;
        private List<News> newsList;

        public NewsAdapter(List<News> newsList, Context context) {
            this.newsList = newsList;
            this.context = context;
            inflater = LayoutInflater.from(context);
        }

        ...         

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final ViewHolder viewHolder;
            if (convertView == null) {
                LayoutInflater row = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = row.inflate(R.layout.image_new_row, null);

                viewHolder = new ViewHolder();
                viewHolder.mTitle = convertView.findViewById(R.id.txtNewsTitle);
                viewHolder.mImage = convertView.findViewById(R.id.imageNews);
                viewHolder.mDescription = convertView.findViewById(R.id.txtDescription);

                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

            News news = newsList.get(position);
            viewHolder.mTitle.setText(news.getTitle());
            viewHolder.mDescription.setText(news.getDescription());
            if (news.getImageUrl() != null){
                ImageLoader.getInstance().displayImage(news.getImageUrl(), viewHolder.mImage);
            }
            else{
                viewHolder.mImage.setImageResource(R.drawable.loading);
            }

            return convertView;
        }

my viewHolder:

        static class ViewHolder {
            private TextView mTitle;
            private TextView mDescription;
            private ImageView mImage;

        }

my activity:

        public class NewsActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

            private static final String ITEM = "item";
            private static final String TITLE = "title";
            private static final String LINK = "link";
            private static final String DESCRIPTION = "description";
            private static final String MEDIA = "media:content";
            private static final String IMAGE_URL = "url";

            private Feed feed;
            private ListView newsListView;
            private ArrayList<News> newsList;
            private NewsAdapter mAdapter;
            private ImageLoaderConfiguration imageLoaderConfiguration;

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_news);

                newsListView = (ListView) findViewById(R.id.newsList);

                this.feed = (Feed) getIntent().getSerializableExtra(Constants.EXTRA_CLICKED_FEED);

                configListView();
            }

            private void configListView() {
                File cacheDir = StorageUtils.getCacheDirectory(this);

                DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                        .showImageForEmptyUri(R.drawable.loading)
                        .showImageOnLoading(R.drawable.loading)
                        .showImageOnFail(R.drawable.loading).cacheInMemory(true).cacheOnDisk(true).build();
                imageLoaderConfiguration = new ImageLoaderConfiguration.Builder(this)
                        .defaultDisplayImageOptions(defaultOptions).build();
                ImageLoader.getInstance().init(imageLoaderConfiguration);

                newsList = new ArrayList<News>();
                mAdapter = new NewsAdapter(newsList, this);
                newsListView.setAdapter(mAdapter);

                newsListView.setOnItemClickListener(this);

                new RssAsyncTask().execute(
                        feed.getUrl());
            }

            private List<News> readXML(InputStream is) {
                List<News> newsList =
                        new ArrayList<News>();

                try {
                    DocumentBuilderFactory factory =
                            DocumentBuilderFactory.newInstance();

                    DocumentBuilder builder =
                            factory.newDocumentBuilder();
                    Document xmlDocument = builder.parse(is);

                    NodeList posts =
                            xmlDocument.getElementsByTagName(ITEM);

                    String title = null, description = null,
                            link = null, image = null;

                    for (int i = 0; i < posts.getLength(); i++) {
                        Node post = posts.item(i);

                        // Cada nó ITEM tem os filhos:
                        // TITLE, DESCRIPTION e LINK
                        NodeList postInfo = post.getChildNodes();

                        for (int j = 0; j < postInfo.getLength(); j++) {
                            Node info = postInfo.item(j);

                            if (TITLE.equals(info.getNodeName())) {
                                title = info.getTextContent();

                            } else if (LINK.equals(
                                    info.getNodeName())) {
                                link = info.getTextContent();

                            } else if (DESCRIPTION.equals(
                                    info.getNodeName())) {
                                description = extractText(info.getTextContent()).trim();
                            } else if (MEDIA.equals(
                                    info.getNodeName())) {
                                image = ((Element) info).getAttribute(IMAGE_URL);
                            }
                        }
                        newsList.add(
                                new News(title, description, link, image));
                    }
                } catch (Throwable e) {
                    e.printStackTrace();
                }
                return newsList;
            }


            class RssAsyncTask extends
                    AsyncTask<String, Void, List<News>> {

                ProgressDialog dialog;

                ...

                @Override
                protected void onPostExecute(List<News> result) {
                    super.onPostExecute(result);
                    dialog.dismiss();
                    newsList.addAll(result);
                    mAdapter.notifyDataSetChanged();
                }


            }
        }

obs: I'm using universal image load api: https://github.com/nostra13/Android-Universal-Image-Loader


Solution

  • put your variable initialization into for loop as shown below so that it re initializes variables to null every time..

                    for (int i = 0; i < posts.getLength(); i++) {
    
                           String title = null, description = null,
                            link = null, image = null;
    
                        Node post = posts.item(i);
    
                        // Cada nó ITEM tem os filhos:
                        // TITLE, DESCRIPTION e LINK
                        NodeList postInfo = post.getChildNodes();
    
                        for (int j = 0; j < postInfo.getLength(); j++) {
                            Node info = postInfo.item(j);
    
                            if (TITLE.equals(info.getNodeName())) {
                                title = info.getTextContent();
    
                            } else if (LINK.equals(
                                    info.getNodeName())) {
                                link = info.getTextContent();
    
                            } else if (DESCRIPTION.equals(
                                    info.getNodeName())) {
                                description = extractText(info.getTextContent()).trim();
                            } else if (MEDIA.equals(
                                    info.getNodeName())) {
                                image = ((Element) info).getAttribute(IMAGE_URL);
                            }
                        }
                        newsList.add(
                                new News(title, description, link, image));
                    }