2011-03-06 9 views
5
rendimiento

Quiero mostrar la foto de contacto en un ListView. Estoy enfrentando un problema de rendimiento (el desplazamiento no es fluido) cuando hay una gran cantidad de contactos. Estoy usando el método getView de ArrayAdapter para asignar una foto de contacto a ImageView. Cuando la imagen no se usa, el desplazamiento es suave.carga foto de contacto en una vista de lista

Pero el desplazamiento aplicación de contactos predeterminada es muy suave. Entonces, hay un problema de rendimiento en mi aplicación.

¿Cómo puedo mejorar el rendimiento? Por favor recomiende.

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

Respuesta

6

Al crear una vista en getView() debe colocar un icono genérico en lugar de la foto, a continuación, iniciar una AsyncTask para cargar la imagen en el fondo y volver de getView() lo más rápido posible. Luego, cuando la imagen está lista (la tarea de fondo AsyncTask está lista), reemplaza el ícono genérico en la vista con la imagen cargada.

De esta manera las imágenes podrían no muestran inmediatamente, pero el desplazamiento será suave.

+0

Lo siento por la respuesta tardía ... Todavía estoy enfrentando el problema después de usar AsyncTask. He agregado el código en mi pregunta. Por favor, eche un vistazo y sugiéralo. –

+0

Llama a 'BitmapFactory.decodeResource' para cada vista nueva. Dado que este es el mismo mapa de bits para cada vista, puede reutilizarlo. –

+0

Un poco mejor después de mover BitmapFactory.decodeResource como miembro de MyArrayListAdapter. Pero aun así, la tartamudez ocurre si me desplazo rápidamente. De todos modos, gracias por tu valiosa ayuda. –

Cuestiones relacionadas