2011-03-06 35 views
5

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

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

我该如何提高性能?请建议。

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

回答

6

当创建在getView()视图,你应该把一个通用的图标代替照片的,然后开始一个的AsyncTask加载图像中的背景,并从getView()快速恢复越好。然后,当图像准备好(AsyncTask后台任务完成)时,将视图中的通用图标替换为加载的图像。

这种方式图像可能不会立即显示,但滚动将平滑。

+0

对不起,迟到的回应...我使用AsyncTask后仍然面临问题。我在我的问题中添加了代码。请看看并建议。 – 2011-03-12 04:42:44

+0

您可以为每个新视图调用'BitmapFactory.decodeResource'。由于这是每个视图的相同位图,因此可以重复使用它。 – 2011-03-12 06:23:42

+0

将BitmapFactory.decodeResource作为MyArrayListAdapter的成员移动后会好一点。但如果我快速滚动,仍会发生口吃。无论如何感谢您的宝贵帮助。 – 2011-03-12 11:45:31