代码如下:
@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();
}
}
- 异步调用启动,用户向下滚动
- 调用完成,获得图像url,Picasso再次发出GET请求以渲染图像,但由于回收,处于错误的图像视图中
我知道解决这个问题的唯一方法是发出第一个get请求(以获得图像链接)SYNCHRONOUS,阻塞ui以确保在加载图像之前不会再次调用getView。有更好的方法来解决这个问题吗?非常感谢。
您看到这种行为的原因是,您只是在发出另一个异步请求后才调用Picasso
对象。这意味着毕加索无法知道这幅作品是为一件新作品而回收的。
解决这个问题的最简单方法是添加对Picasso的调用,以取消对回收视图的现有请求。
Picasso.with(getContext()).cancelRequest(viewHolder.profileIV)
这应该在APIclient.getImageJson
调用的外部执行,以便在调用适配器时同步运行。