【问题标题】:Android ListView repeat imageAndroid ListView 重复图片
【发布时间】:2018-02-26 22:23:34
【问题描述】:

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

这是我的适配器:

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

我的视图持有者:

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

        }

我的活动:

        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

【问题讨论】:

  • 你初始化getview方法了吗?
  • 每当您在适配器中显示图像或数据时,您应该有 if else case 和 image 如果图像不可用,只需将资源设置为 null
  • @skyshine 当图像不可用时,我在此行中设置了默认图像:viewHolder.mImage.setImageResource(R.drawable.loading);
  • 首先设置为 null 然后设置一些占位符
  • @skyshine 你是说://首先制作这个 viewHolder.mImage.setImageBitmap(null); //在这个viewHolder.mImage.setImageResource(R.drawable.loading);之后

标签: android listview universal-image-loader


【解决方案1】:

将变量初始化放入如下所示的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));
                }

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • @VictorGuedes 如果第一种方法不起作用,请检查 news.getImageUrl() - 你必须有相同的 url 重复
    【解决方案3】:

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

    viewHolder = (ViewHolder) convertView.getTag();
    

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

    【讨论】:

    • 我该怎么做?
    猜你喜欢
    • 2012-07-29
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多