在Android Studio中的自定义适配器中从URL加载图像(ListView)

4

虽然位图似乎被正确获取,但变量'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
            }
        }
    }

}

}


3
我会使用Picasso,过上快乐的生活。 - Emmanuel
2个回答

7
解决问题最简单的方法是使用一些库,例如Picasso。它不仅易于使用和使您的代码易于阅读,而且在图像过大时还可以防止OutOfMemory异常。加载图像只需要一行代码:
Picasso.with(context)
.load(urlOfYourImage)
.resize(50, 50) // here you resize your image to whatever width and height you like
.into(imageView)

哦,我的。这是为我准备的。 - user2892437
希望这可以帮助到您。简化一下就好了。;) - Jerry
一行代码就可以解决问题,真是不可思议。你认为我是否还应该使用异步? - user2892437
将以下代码行添加到build.gradle的依赖项中:compile 'com.squareup.picasso:picasso:2.5.2' - Jerry

0

我认为你在这里遇到了两个问题:

1)视图回收 - 我自己也是Android的新手,当使用listviews时,这经常会出现,当列表的某些部分移动到屏幕外时,它们在向后滚动时可能会出错。我个人在其中一个问题上遇到了按钮状态更改错误的情况。这个教程更详细地介绍了Recycling,并提供了一个View Holder私有类的解决方案,这对我很有效。我相信SO的其他部分也谈论了这个问题。

2)图像为空 - 这肯定是作为null传递过来的吗,还是只是没有出现在listview中?如果是前者,则LoadImage()中的某些步骤必须不正确。如果是后者,则可以尝试在设置图像后调用notifyDataSetChanged(),告诉主线程图像已准备好绘制。类似下面的内容(在您的AsyncTask中):

@Override
protected void onPostExecute() {
       notifyDataSetChanged();
    }
}

谢谢评论。notifyDataSetChange();有所帮助。现在,所有视图都有图片。但是,它们都是相同的,并且每秒钟更改一次(而文本视图保持不变/正确)。我认为这与在getView()之外定义'userBitmap'有关。有更好的方法吗? - user2892437

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接