Android开发:如何在ListView中使用Picasso加载URL网络图片?
Hey Kyle, let's break this down clearly so you can get your image loading working smoothly:
You should load images directly in your ListView's Adapter, specifically inside the getView() method (or onBindViewHolder() if you were using RecyclerView). Here's why:
- ListView only renders items visible on screen (plus a few off-screen for smooth scrolling). Loading images here ensures you only fetch and load images when they're needed, saving memory and network bandwidth.
- This aligns with ListView's view recycling pattern—you'll reuse existing views and load images into them as they scroll into view.
Yes, you can absolutely keep your HashMap to store parsed JSON data (including image URLs). That said, a custom model class (like ListItem with explicit fields for imageUrl, title, etc.) will make your code more readable and less error-prone than relying on string keys for HashMap. But if you're already comfortable with the HashMap approach, it works perfectly fine as your Adapter's data source.
loadListView() Don't do this! Loading all images upfront (before setting the adapter) wastes resources:
- You'll download images for items the user might never see (if they don't scroll all the way).
- Loading dozens/hundreds of images at once can trigger memory issues (like OutOfMemoryError) and slow down your app.
Example Adapter Code with Picasso
Here's how to implement this in your Adapter:
public class MyListAdapter extends BaseAdapter { private Context mContext; private List<HashMap<String, String>> mData; // Constructor public MyListAdapter(Context context, List<HashMap<String, String>> data) { mContext = context; mData = data; } @Override public int getCount() { return mData.size(); } @Override public Object getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; // Reuse views with ViewHolder pattern if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.your_list_item_layout, parent, false); holder = new ViewHolder(); holder.itemImage = convertView.findViewById(R.id.item_image_view); holder.itemText = convertView.findViewById(R.id.item_text_view); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // Get current item data from your HashMap HashMap<String, String> currentItem = mData.get(position); String imageUrl = currentItem.get("image"); // Match your JSON "image" key String itemText = currentItem.get("your_other_field"); // Replace with your actual data field // Load image with Picasso Picasso.get() .load(imageUrl) .placeholder(R.drawable.placeholder) // Optional: show while loading .error(R.drawable.error_image) // Optional: show if load fails .into(holder.itemImage); // Set other text content holder.itemText.setText(itemText); return convertView; } // ViewHolder to cache views for recycling static class ViewHolder { ImageView itemImage; TextView itemText; } }
In Your MainActivity
After parsing your JSON into the List<HashMap<String, String>>, just initialize the adapter and set it to your ListView—no pre-loading images needed:
// After parsing JSON into dataList MyListAdapter adapter = new MyListAdapter(this, dataList); yourListView.setAdapter(adapter);
That's it! This approach is efficient, follows Android best practices, and keeps your code organized.
内容的提问来源于stack exchange,提问作者Kyle

