在 ListView 的自定义适配器中从 URL 加载图像(Android Studio)
Posted
技术标签:
【中文标题】在 ListView 的自定义适配器中从 URL 加载图像(Android Studio)【英文标题】:Loading image from URL in custom adapter for ListView (Android Studio) 【发布时间】:2015-07-09 09:27:21 【问题描述】:虽然位图似乎被正确提取,但变量“userBitmap”将保持为空。但是,当在我的平板电脑上向上或向下滚动时,新的列表行将包含图片,但它们都是相同且错误的。真的,真的很迷茫。我尝试了许多不同的方法从网络上获取图像。非常感谢任何帮助。
我的自定义适配器:
public class MessagesArrayAdapter extends ArrayAdapter<ChatData>
Bitmap userBitmap;
public MessageArrayAdapter(Context context, List<ChatData> objects)
super(context, 0, objects);
public View getView(int position, View convertView, ViewGroup parent)
ChatCell chatCell = new ChatCell();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.cell_chat, parent, false);
chatCell.usernameTextView = (TextView) convertView.findViewById(R.id.usernameTextView);
chatCell.messageTextView = (TextView) convertView.findViewById(R.id.messageTextView);
chatCell.userImageView = (ImageView) convertView.findViewById(R.id.userImageView);
ChatData chatData = getItem(position);
// Get user image from web
new loadImageAsync().execute(chatData.avatarURL);
chatCell.userImageView.setImageBitmap(userBitmap);
chatCell.usernameTextView.setText(chatData.username);
chatCell.messageTextView.setText(chatData.message);
return convertView;
private static class ChatCell
TextView usernameTextView;
TextView messageTextView;
ImageView userImageView;
private class loadImageAsync extends AsyncTask<String, Void, Double>
@Override
protected Double doInBackground(String... params)
userBitmap = loadImage(params[0]);
return null;
public Bitmap loadImage(String str)
InputStream instream = null;
try
HttpGet httpRequest = new HttpGet(URI.create(str));
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
instream = bufHttpEntity.getContent();
Bitmap myBitmap = BitmapFactory.decodeStream(instream);
return myBitmap;
catch (Exception e)
e.printStackTrace();
return null;
finally
//close input
if (instream != null)
try
instream.close();
catch (IOException ioex)
// Handle error
【问题讨论】:
我会使用Picasso,过上幸福的生活。 【参考方案1】:解决问题的最简单方法是使用一些库,例如 Picasso。它不仅更易于使用并使您的代码更易于阅读,而且还可以防止您在图像太大时出现 OutOfMemory 异常。加载图像只需一行:
Picasso.with(context)
.load(urlOfYourImage)
.resize(50, 50) // here you resize your image to whatever width and height you like
.into(imageView)
【讨论】:
天哪。这是给我的。 希望这会有所帮助。只是简化。 ;) 一切都在一行代码中运行。不敢相信。你认为我还应该使用异步吗? 将这行代码添加到 build.gradle 中的依赖项中: compile 'com.squareup.picasso:picasso:2.5.2'【参考方案2】:我认为您在这里遇到了两个问题:
1) 视图回收 - 我自己是 android 新手,在使用列表视图时经常出现这种情况,当部分列表视图移出屏幕时,它们在向后滚动时可能会出错。我个人在上下滚动时遇到了按钮状态更改为错误行的问题。 This tutorial 更详细地介绍了回收是什么,并在对我有用的 View Holder 私有类中提供了一个解决方案。我相信 SO 的其他部分也会讨论这个问题。
2) Image Null - 这肯定是 null,还是只是没有出现在列表视图中?如果是前者,则 LoadImage() 中的某些步骤一定不能正常工作。如果是后者,您可能想在设置图像后尝试调用 notifyDataSetChanged(),以告诉主线程图像已准备好绘制。如下所示(在您的 AsyncTask 中):
@Override
protected void onPostExecute()
notifyDataSetChanged();
【讨论】:
感谢您的评论。 notifyDataSetChange();帮助。现在,所有的视图都有图片。但是,它们都是相同的,并且每秒都在变化(而文本视图保持不变/正确)。我认为这与在 getView() 之外定义的“userBitmap”有关。有没有更好的方法来做到这一点?以上是关于在 ListView 的自定义适配器中从 URL 加载图像(Android Studio)的主要内容,如果未能解决你的问题,请参考以下文章
Android ListView 和带有 ViewHolder 的自定义适配器
具有包含 CheckBoxes 的自定义适配器的 Listview
带有过滤器 Android 的自定义 Listview 适配器
如何在 listview onClick() 中从 POJO 获取项目?
ArrayIndexOutOfBoundsException 与 ListView 中的多个视图的自定义 Android 适配器