【问题标题】:Load contact photo in a listview performance在列表视图性能中加载联系人照片
【发布时间】:2011-03-06 16:15:22
【问题描述】:

我想在 ListView 中显示联系人的照片。当有大量联系人时,我面临性能问题(滚动不流畅)。我正在使用 ArrayAdapter 的 getView 方法将联系人照片分配给 ImageView。当不使用图像时,滚动是平滑的。

但是默认的联系人应用滚动非常流畅。所以我的应用程序存在性能问题。

如何提高性能?请提出建议。

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

【问题讨论】:

    标签: android contacts photo


    【解决方案1】:

    getView() 中创建视图时,您应该放置一个通用图标来代替照片,然后启动一个 AsyncTask 以在后台加载图像并尽快从getView() 返回。然后当图像准备好(AsyncTask 后台任务完成)时,您将视图中的通用图标替换为加载的图像。

    这样图像可能不会立即显示,但滚动会很流畅。

    【讨论】:

    • 抱歉回复晚了...我在使用 AsyncTask 后仍然面临这个问题。我在我的问题中添加了代码。请看一下并提出建议。
    • 您为每个新视图调用BitmapFactory.decodeResource。由于这是每个视图的相同位图,您可以重复使用它。
    • 将 BitmapFactory.decodeResource 移动为 MyArrayListAdapter 的成员后会好一些。但是如果我快速滚动,仍然会出现口吃。无论如何感谢您的宝贵帮助。
    • 您好,我找到了口吃的原因。在 getView 中调用 getContactDisplayName(cb.getContactIndex()) 是真正的罪魁祸首,现在在 ContactsBook 中添加了 Displayname 作为另一个字段并从那里获取 DisplayName。现在真的很顺利。感谢您告知 AsyncTask 它真的很有用。
    • 很高兴听到这个消息。是的,数据库查询也需要时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 2011-01-23
    • 2014-07-12
    • 1970-01-01
    • 2013-08-12
    相关资源
    最近更新 更多