2011-03-06 87 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