1

そのため、画像のダウンロードとキャッシュにPicasso Libraryを使用しようとしています。contactUri を渡すにPicassoは、 Contacts に対してクエリを実行する必要がありますContent Provider。contactId を取得するためにメイン UI スレッドをブロックしたくないので、これをAsyncTask. そして、その contactId を取得したら、PicassoonPostExecute()メソッドで を呼び出しますAsyncTask

ただし、ListViewすばやくスクロールするとちらつきが表示されることに気付きました。ViewHolder適切な画像を設定する前に、リサイクルされたビューが前の画像を表示しているため、に問題があるようです。とにかくこれを回避する方法はありますか?

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;
    // 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);


        }

        mCursor = getCursor();

        mCursor.moveToPosition(position);

        viewHolder.position = position;

        String recipient_ids = mCursor.getString(RECIPIENT_IDS_COLUMN_INDEX);

        String[] recipients = recipient_ids.split(" ");

        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;
    }

    private class AddressFetcherTask extends AsyncTask < String[], Void, Integer > {
        private ViewHolder mViewHolder;
        private int mPosition;

        public AddressFetcherTask(ViewHolder viewHolder, int position) {
            mViewHolder = viewHolder;
            mPosition = position;
        }

        @Override
        protected Integer doInBackground(String[]...recipients) {
            String recipient = recipients[0][0];
            Log.d(DEBUG_TAG, "recipient is " + recipient);
            Cursor c = mContentResolver.query(
            Uri.parse("content://mms-sms/canonical-addresses"), null, "_id = " + recipient, 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) {
                Picasso.with(mContext)
                    .load(getContactUri(contactId))
                    .placeholder(R.drawable.ic_contact_picture)
                    .into(mViewHolder.contactBadge);

            }
        }
    }
    // endregion

}
4

1 に答える 1