Android ListView 重复图片

Android ListView repeat image

我正在 android 上实现一个包含图像视图的列表视图,但我遇到了一个问题: 当一行没有图像时,它会重复前一项的图像。

这是我的适配器:

    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;
        }

我的 viewHolder:

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

        }

我的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:我正在使用通用图像加载 api: https://github.com/nostra13/Android-Universal-Image-Loader

当然可以...您正在重复使用前一项的布局。这就是下面语句的意思。

viewHolder = (ViewHolder) convertView.getTag();

如果您没有在 getView 方法中对其进行初始化,它将显示与上一项相同的内容。

根据您的代码 - 图片下载失败时可能会发生这种情况。 您可以使用:

viewHolder.mImage.setImageResource(R.drawable.loading);        
if (news.getImageUrl() != null){
    ImageLoader.getInstance().displayImage(news.getImageUrl(), viewHolder.mImage);
}

您可以使用以下代码:

ImageLoader.getInstance().displayImage(imageUri, imageView, options, new ImageLoadingListener() {
    @Override
    public void onLoadingStarted(String imageUri, View view) {
    ...
    }
    @Override
    public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
        ...
    }
    @Override
    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
        ...
    }
    @Override
    public void onLoadingCancelled(String imageUri, View view) {
        ...
    }
}
});

如下所示将您的变量初始化放入for循环中,以便它每次都将变量初始化为null..

                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));
                }