Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
259 views
in Technique[技术] by (71.8m points)

android - Load contact photo in a listview performance

I want to display contact's photo in a ListView. I am facing performance problem(Scrolling is not smooth) when there is a large number of contacts. I am using ArrayAdapter's getView method to assign contact photo to ImageView. When image is not used then scrolling is smooth.

But the default contact application scrolling is very smooth. So there is a performance problem in my application.

How can I improve the performance? Please suggest.

private class MyArrayListAdapter extends ArrayAdapter<ContactsBook> implements OnItemClickListener{
    private ArrayList<ContactsBook> mContacts;
    private Context mContext;


    public MyArrayListAdapter(Context context, int textViewResourceId, ArrayList<ContactsBook> contacts) {
        super(context, textViewResourceId, contacts);
        mContacts= contacts;
        mContext=context;
    }
    @Override
    public View getView(int position, View converview, ViewGroup parent){

        View view=converview;
        ViewHolder viewHolder=new ViewHolder();
        if(view==null){
            LayoutInflater inflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view=inflater.inflate(R.layout.phone_row, null);
            viewHolder.tvName=(TextView)view.findViewById(R.id.tvContact);
            viewHolder.tvPhoneNo=(TextView)view.findViewById(R.id.tvPhoneNo);
            viewHolder.qcBadge=(QuickContactBadge)view.findViewById(R.id.qContact);
            view.setTag(viewHolder);
        }
        else
            viewHolder=(ViewHolder) view.getTag();
        ContactsBook cb=mContacts.get(position);
        if(cb!=null){
            Uri contactPhotoUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,cb.getContactIndex());
            BitmapDownloaderTask bdTask=new BitmapDownloaderTask(viewHolder.qcBadge);
            bdTask.execute(contactPhotoUri.toString());
            viewHolder.qcBadge.assignContactUri(contactPhotoUri);
            viewHolder.qcBadge.setImageBitmap(framePhoto(BitmapFactory.decodeResource(getResources(), R.drawable.ic_contact_list_picture)));
            viewHolder.tvName.setText(getContactDisplayName(cb.getContactIndex()));
            viewHolder.tvPhoneNo.setText(getContactPhoneNo(cb.getContactIndex()));
        }
        return view;

    }
    class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
        private String url;
        private final WeakReference<ImageView> imageViewReference;


        public BitmapDownloaderTask(ImageView imageView) {
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        /**
         * Actual download method.
         */
        @Override
        protected Bitmap doInBackground(String... params) {
            url = params[0];
            Uri conUri=Uri.parse(url);
            InputStream photoInputStream=Contacts.openContactPhotoInputStream(mContext.getContentResolver(), conUri);
            if(photoInputStream==null)
                return framePhoto(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_contact_list_picture));
            Bitmap photo=framePhoto(getPhoto(mContext.getContentResolver(), conUri));

            return photo;
        }
    /**
         * Once the image is downloaded, associates it to the imageView
         */
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (isCancelled()) {
                bitmap = null;
            }
            if (imageViewReference != null) {
                ImageView imageView = imageViewReference.get();
                imageView.setImageBitmap(bitmap);
            }
        }
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When creating a view in getView() you should place a generic icon in place of photo, then start an AsyncTask to load the image in the background and return from getView() as fast as possible. Then when image is ready (AsyncTask background task is done) you replace the generic icon in the view with the loaded image.

This way images might not show immediately, but the scrolling will be smooth.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...