Reputation: 178
The code looks like this:
@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();
}
}
The only way I know to get around this is to make the first GET request(to obtain the image link) SYNCHRONOUS, blocking the ui to make sure getView isn't called again before the image is loaded. Is there a better way to get around this? Many thanks in advance.
Upvotes: 2
Views: 1307
Reputation: 76125
The reason you are seeing this behavior is that you are only calling the Picasso
object after making another asynchronous request. This means that Picasso has no way of knowing that the view was recycled for a new item.
The easiest way to solve this is by adding a call to Picasso to cancel existing requests for the recycled view.
Picasso.with(getContext()).cancelRequest(viewHolder.profileIV)
This should be done outside of the APIclient.getImageJson
call so that it runs synchronously when the adapter is called.
Upvotes: 4