listview中的图像错误,因为imageview已回收



代码如下:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final Contact currContact = getItem(position);
    final ViewHolder viewHolder;
    if (convertView == null) {
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.contact_item, parent, false);
        viewHolder.profileIV = (ImageView) convertView.findViewById(R.id.profileIV);
        viewHolder.nameTV = (TextView) convertView.findViewById(R.id.nameTV);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
**************************PER JAKE WHARTON's RESPONSE******************************************
        Picasso.with(getContext()).cancelRequest(viewHolder.profileIV);
    }
    String currName = currContact.getName();
    /* 1 
       Asynchronously GETs https://ajax.googleapis.com/ajax/services/search/images? 
       rsz=8&start=0&v=1.0&imgsz=medium&imgtype=linear&q=(currName) */
    APIclient.getImageJson(getContext(), currName, new JsonHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject imgJson) {
            try {
                JSONObject responseDataValue = imgJson.getJSONObject("responseData");
                JSONArray resultsValue = responseDataValue.getJSONArray("results");
                JSONObject result = resultsValue.getJSONObject(0);
                String imgUrl = result.getString("url");
                // 2
                Picasso.with(getContext()).load(imgUrl).into(viewHolder.profileIV);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
  1. 异步调用启动,用户向下滚动
  2. 调用完成,获得图像url,Picasso再次发出GET请求以渲染图像,但由于回收,处于错误的图像视图中

我知道解决这个问题的唯一方法是发出第一个get请求(以获得图像链接)SYNCHRONOUS,阻塞ui以确保在加载图像之前不会再次调用getView。有更好的方法来解决这个问题吗?非常感谢。

您看到这种行为的原因是,您只是在发出另一个异步请求后才调用Picasso对象。这意味着毕加索无法知道这幅作品是为一件新作品而回收的。

解决这个问题的最简单方法是添加对Picasso的调用,以取消对回收视图的现有请求。

Picasso.with(getContext()).cancelRequest(viewHolder.profileIV)

这应该在APIclient.getImageJson调用的外部执行,以便在调用适配器时同步运行。

相关内容

  • 没有找到相关文章

最新更新