Picasso loading of image spawned inside AsyncTask

后端 未结 1 742
不思量自难忘°
不思量自难忘° 2020-11-29 10:45

So I am trying to use the Picasso Library for image downloading and caching. In order to get the contactUri to pass to Picasso I need to make a query to the Co

相关标签:
1条回答
  • 2020-11-29 11:19

    Just set the imageview to null in within getView and it should remove what you are experiencing for the most part you'll be right.

    The other tiny tiny corner case aspect is that when your asynctask arrives at postExecute, the view might still exist, but it might have already been assigned a different contact to load up (it's been recycled).

    You need to put some kind of tag in the viewholder, and then check that it is still the same when you go to set it in postexecute.

    To remove the fade in, you need to remove the asynctask from the getview. You need to be able to call picasso within getview, which means having your data ready before arriving at getview.

    The below, not quite sure if it will compile, I've done it in a text editor.

    But bassically I'm caching results in mCachedContactIds and just reloading the whole table if I need a new one. I've typically found this to be robust. But you can also call the picasso code which I've commented out

    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
    
    }
    

    Or if all that's bugging you left is the fade from picasso, then add noFade() to the request.

    0 讨论(0)
提交回复
热议问题