所以我试图使用Picasso Library进行图像下载和缓存。为了让contactUri传递给Picasso
,我需要查询联系人Content Provider
。由于我不想阻止主UI线程获取contactId,因此我将其放在AsyncTask
中。一旦我获得了contactId,我就会在Picasso
的{{1}}方法中拨打onPostExecute()
。
然而,我注意到当我快速滚动AsyncTask
时出现的闪烁现象。在我看来,ListView
存在问题,因为在设置适当的图像之前,回收的视图正在显示上一个图像。反正有没有避免这个?
ViewHolder
答案 0 :(得分:3)
只需在getView中将imageview设置为null,它就应该删除你正在经历的大部分内容。
另一个微小的小角落情况是,当你的asynctask到达postExecute时,视图可能仍然存在,但它可能已被分配了一个不同的联系人来加载(它已被回收)。
您需要在视图中放置某种标记,然后在postexecute中设置它时检查它是否仍然相同。
要删除淡入,您需要从getview中删除asynctask。您需要能够在getview中调用picasso,这意味着在到达getview之前准备好数据。
下面,不太确定它是否会编译,我已经在文本编辑器中完成了。
但是低音我正在缓存mCachedContactIds中的结果,如果我需要一个新表,只需重新加载整个表。我通常发现这很强大。但你也可以调用我已经注释掉的毕加索代码
public class ConversationThreadsCursorAdapter extends SimpleCursorAdapter {
// region Constants
private static final int RECIPIENT_IDS_COLUMN_INDEX = 3;
private static final int ID2_COLUMN_INDEX = 0;
private static final int ADDRESS_COLUMN_INDEX = 1;
private HashMap<String, Integer> mCachedContactIds = new HashMap<String, Integer>();
// endregion
// region Variables
private final String DEBUG_TAG = getClass().getSimpleName().toString();
private Context mContext;
protected Drawable mDefaultPicDrawable;
protected ContentResolver mContentResolver;
protected LinearLayout.LayoutParams mContactPicLayoutParams;
// endregion
// region Constructors
public ConversationThreadsCursorAdapter(Context context, int layout,
Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
mContext = context;
mDefaultPicDrawable = mContext.getResources().getDrawable(
R.drawable.ic_contact_picture);
mContactPicLayoutParams = new LinearLayout.LayoutParams(
mDefaultPicDrawable.getIntrinsicWidth(),
mDefaultPicDrawable.getIntrinsicHeight());
}
// endregion
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.simple_message, null);
// Creates a ViewHolder and store references to the children
// views we want to bind data to.
viewHolder = setupViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.task.cancel(true);
viewHolder.contactBadge.setImageDrawable(mDefaultPicDrawable);
}
mCursor = getCursor();
mCursor.moveToPosition(position);
viewHolder.position = position;
String recipient_ids = mCursor.getString(RECIPIENT_IDS_COLUMN_INDEX);
String[] recipients = recipient_ids.split(" ");
String recipient = recipients[0];
if(mCachedContactIds.get(recipient) != null){
Picasso.with(mContext)
.load(getContactUri(mCachedContactIds.get(recipient)))
.placeholder(R.drawable.ic_contact_picture)
.into(mViewHolder.contactBadge);
} else {
viewHolder.task = new AddressFetcherTask(viewHolder, position);
viewHolder.task.execute(recipients);
}
return convertView;
}
// region Helper Methods
private ViewHolder bindUIElements(View convertView) {
ViewHolder viewHolder = new ViewHolder();
viewHolder.contactBadge = (QuickContactBadge) convertView.findViewById(R.id.contact_pic);
return viewHolder;
}
private ViewHolder setupViewHolder(View convertView) {
ViewHolder viewHolder = bindUIElements(convertView);
viewHolder.contactBadge.setLayoutParams(mContactPicLayoutParams);
return viewHolder;
}
// endregion
// region Inner Classes
private class ViewHolder {
QuickContactBadge contactBadge;
int position;
AddressFetcherTask task;
}
private class AddressFetcherTask extends AsyncTask < String[], Void, Integer > {
private ViewHolder mViewHolder;
private int mPosition;
private String mRecipient;
public AddressFetcherTask(ViewHolder viewHolder, int position) {
mViewHolder = viewHolder;
mPosition = position;
}
@Override
protected Integer doInBackground(String[]...recipients) {
mRecipient = recipients[0][0];
Log.d(DEBUG_TAG, "recipient is " + recipient);
Cursor c = mContentResolver.query(
Uri.parse("content://mms-sms/canonical-addresses"), null, "_id = " + mRecipient, null, null);
String _id = "";
String address = "";
while (c.moveToNext()) {
_id = c.getString(ID2_COLUMN_INDEX);
address = c.getString(ADDRESS_COLUMN_INDEX);
}
c.close();
int contactId;
if (address != null) {
contactId = ContactsUtils.getContactId(mContext, address, "address");
} else {
contactId = Integer.valueOf(address);
}
return contactId;
}
@Override
protected void onPostExecute(Integer contactId) {
if (mViewHolder.position == mPosition) {
mCachedContactIds.put(mRecipient, contactId);
Picasso.with(mContext)
.load(getContactUri(mCachedContactIds.get(recipient)))
.placeholder(R.drawable.ic_contact_picture)
.into(mViewHolder.contactBadge);
}
}
}
// endregion
}
或者,如果所有这些让你感到困扰的是毕加索的淡出,那么在请求中添加noFade()。