我可以下载图像并将其显示在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方库,因为其他聪明人也遇到过这个问题并提出了很好的解决方案:
它们都有一个非常(非常)简单的 Api 来完成工作,而且它们都非常高效且可调,默认情况下已经有很好的设置。
关于java - 在 ListView 中从 URL 加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28062119/