java - 在 ListView 中从 URL 加载图像

标签 java android listview

我可以下载图像并将其显示在ListView中。但我面临的问题是, 当我加载图像时,它们全部加载到列表的第一行。第一行显示正在逐个加载。而其他行保存默认图像。它看起来很奇怪。该怎么办。代码如下:

            private class simpsync extends AsyncTask<String, Integer , Bitmap>{
                private final WeakReference imageViewReference;
                simpsync(ImageView iv){
                    //imageView=iv;
                    imageViewReference=new WeakReference(iv);

                }
                @Override
                protected Bitmap doInBackground(String... param) {

                    Bitmap bmp=CommonFunctions.overlay(CommonFunctions.loadUrlBitmap(param[0]));
                    return bmp;
                }
                  protected void onPostExecute(Bitmap bitmap) {

                      //imageView.setImageBitmap(result);
                      if (isCancelled()) {
                            bitmap = null;
                        }
                        if (imageViewReference != null) {
                            ImageView imageView = (ImageView) imageViewReference.get();
                            if (imageView != null) {

                                if (bitmap != null) {
                                    imageView.setImageBitmap(bitmap);
                                }
                                }
                            }
                  }
            }

这段代码是BaseAdapter类的getView函数

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

                View vi = convertView;
                ViewHolder holder;

                if(convertView==null){

                    /****** Inflate tabitem.xml file for each row ( Defined below ) *******/
                    //list_book_detail_entry
                    if(requestType==SearchAndIndex.SEARCH_IN_SEPAERATE)
                    {
                        vi = inflater.inflate(R.layout.list_book_detail_buy, parent, false);
                        //vi = inflater.inflate(R.layout.list_book_detail_buy, null);
                    }
                    else{
                        vi = inflater.inflate(R.layout.list_book_detail_entry, parent, false);
                        //vi = inflater.inflate(R.layout.list_book_detail_entry, parent, false);
                    }


                    /****** View Holder Object to contain tabitem.xml file elements ******/

                    holder = new ViewHolder();

                    holder.bookTitle=(TextView)vi.findViewById(R.id.BookTitle);
                    holder.writer = (TextView) vi.findViewById(R.id.WriterName);
                    holder.imageUrl=(ImageView)vi.findViewById(R.id.ImageUrl);
                    holder.isbn=(TextView)vi.findViewById(R.id.BookISBN);
                    holder.serialNumber=(TextView)vi.findViewById(R.id.BookSerialNumber);
                    holder.availabilityView=(ImageView)vi.findViewById(R.id.AvailabilityView);
                    holder.publisher=(TextView)vi.findViewById(R.id.Publisher);
                    holder.publishingDate=(TextView)vi.findViewById(R.id.PublishingDate);
                    /************  Set holder with LayoutInflater ************/
                    vi.setTag( holder );
                }
                else 
                    holder=(ViewHolder)vi.getTag();

                if(data.size()<=0)
                {
                    holder.bookTitle.setText("--");
                    holder.writer.setText("--");
                    holder.publisher.setText("--");
                    holder.publisher.setText("----+--+--");
                }
                else
                {
                    tempValues=null;
                    tempValues = ( BookDetailsStruct ) data.get( position );
                    holder.writer.setText( tempValues.Writer );
                    holder.publisher.setText(tempValues.Publisher);
                    holder.publishingDate.setText(tempValues.getIssueDetail(0).publishingDate);

                    simpsync sp=new simpsync(holder.imageUrl);
                    if(requestType==SearchAndIndex.SEARCH_IN_SEPAERATE)
                     {
                         if(tempValues.getIssueDetail(0)!=null)
                         {
                             String toAdd;
                             if(tempValues.getIssueDetail(0).serialNumber==-1)
                                 toAdd="";
                             else
                                 toAdd=" [ 巻"+tempValues.getIssueDetail(0).serialNumber+" ]";
                             holder.bookTitle.setText( tempValues.BookName+toAdd);
                             sp.execute(tempValues.getIssueDetail(0).smallImageUrl);
                         }
                     }
                     else{
                         if(tempValues.largetNumberIndex!=-1)
                         {
                             String toAdd;
                             if(tempValues.getIssueDetail(tempValues.largetNumberIndex).serialNumber==-1)
                                 toAdd="";
                             else
                                 toAdd=" ("+tempValues.getIssueCount()+"巻)";
                             holder.bookTitle.setText( tempValues.BookName+toAdd);
                             sp.execute(tempValues.getIssueDetail(tempValues.largetNumberIndex).smallImageUrl);
                         }
                         else{
                             holder.bookTitle.setText( tempValues.BookName);
                             sp.execute(tempValues.getIssueDetail(0).smallImageUrl);
                         }
                     }
                     vi.setOnClickListener(new OnItemClickListener( position ));
                }
                return vi;

            }

如果您还有任何疑问,请告诉我

最佳答案

“问题”是ListView的回收行为。你对它的尊重还不够。当您向下滚动并且 View 在顶部消失时,它将在底部重用(这就是您使用 ViewHolder 模式的原因,这很好)。但您也可以启动一个异步任务并为其提供 ImageView 并保留它。由于行的整个 View (以及 imageview)被回收,因此它不符合垃圾回收的条件,因此 asynctask 有一个有效的 ImageView 来在完成后显示图像。

要更正您的代码,我建议您只需修改 Android 开发人员页面上编写的内容,它几乎是复制粘贴就绪的代码供您使用: Load Bitmaps into a GridView Implementation

您也可以使用第3方库,因为其他聪明人也遇到过这个问题并提出了很好的解决方案:

  1. Glide
  2. Picasso

它们都有一个非常(非常)简单的 Api 来完成工作,而且它们都非常高效且可调,默认情况下已经有很好的设置。

关于java - 在 ListView 中从 URL 加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28062119/

相关文章:

java - jspc-maven-plugin 由于缺少类而无法编译

java - Elasticsearch 和 mongodb,部分搜索不起作用

java - 如何实例化封装对象?

android - Jetpack 撰写 : Custom VectorAsset Icon object similar to built-in `Icons.Default`

android - 将项目添加到数据源不会出现在 ListView 中

java - 对于带有 JAXB 注释的类,是否有类似 PostConstruct 的东西?

android - 如果像 flipkart 价格范围一样在 RecyclerView 中检查过,如何将复选框设置为 true

android绑定(bind)库 protected 成员

java - Android - 禁用 ListView 选择突出显示但保持 OnClick 启用

c# - UWP 中 ListView 中的 header 元素