2009-08-24 5 views
11

Cargo datos de Cursor a listview, pero mi Listview realmente no muestra "smooth". Los datos cambian cuando arrastro arriba y abajo en la barra scoll en mi ListView. Y algunos elementos parecen duplicados en mi lista. Tengo un "ListView complejo" (dos textview, one imageview) Así que utilicé newView(), bindView() para visualizar datos. ¿Alguien me puede ayudar?Cómo cargar la Listview "sin problemas" en android

Respuesta

11

Le describiré cómo obtener el problema que tiene. Posiblemente esto te ayudará.

Así, el adaptador lista que ha dicho código:

public View getView(int position, View contentView, ViewGroup arg2) 
    { 
     ViewHolder holder; 

     if (contentView == null) { 
      holder = new ViewHolder(); 
      contentView = inflater.inflate(R.layout.my_magic_list,null); 
      holder.label = (TextView) contentView.findViewById(R.id.label); 
      contentView.setTag(holder); 
     } else { 
      holder = (ViewHolder) contentView.getTag(); 
     } 

     holder.label.setText(getLabel()); 

     return contentView; 
    } 

Como se puede ver, que establece el valor de lista de elementos sólo después de haber recuperado soporte.

Pero si se mueve por encima de código en sentencia if:

holder.label.setText(getLabel()); 

lo que se verá después, como a continuación:

if (contentView == null) { 
    holder = new ViewHolder(); 
    contentView = inflater.inflate(R.layout.my_magic_list,null); 
    holder.label = (TextView) contentView.findViewById(R.id.label); 
    holder.label.setText(getLabel()); 
    contentView.setTag(holder); 
} 

tendrá su comportamiento de la aplicación actual con la duplicación lista de elementos.

Posiblemente le ayude.

+0

Esto también ayuda. Gracias – Dennie

7

ListView es una bestia complicada.

Su segunda pregunta primero: está viendo duplicados porque ListView utiliza de nuevo las Vistas a través de convertView, pero no se está asegurando de restablecer todos los aspectos de la vista convertida. Asegúrese de que la ruta del código para convertView!=null establece correctamente todos los datos para la vista, y todo debería funcionar correctamente.

usted quiere que su método getView() a mirar más o menos como la siguiente si utiliza vistas personalizadas:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final MyCustomView v = convertView!=null ? (MyCustomView)convertView : new MyCustomView(); 
    v.setMyData(listAdapter.get(position)); 
    return v; 
} 

Si no está utilizando su propia vista personalizada, basta con sustituir la llamada a new MyCustomView() con una llamada a inflater.inflate(R.layout.my_layout,null)

en cuanto a su primera pregunta, usted quiere ver TechTalk de Romain en el rendimiento ListView aquí: http://code.google.com/events/io/sessions/TurboChargeUiAndroidFast.html

de su conferencia y con el fin de im portancia de mi propia experiencia,

  • Uso convertView
  • Si tiene imágenes, no se escalan sus imágenes sobre la marcha. Utilice Bitmap.createScaledBitmap para crear un mapa de bits a escala y poner esto en sus puntos de vista
  • utilizar un ViewHolder por lo que no tiene que llamar a un montón de findViewByIds() cada vez que
  • Disminuir la complejidad de las vistas en su vista de lista. Cuantas menos subvistas, mejor. RelativeLayout es mucho mejor en esto que, por ejemplo, LinearLayout. Y asegúrate de usarlo si estás implementando vistas personalizadas.
+0

Disculpe, pero uso newView(), bindView() para mostrar datos. es el mismo problema? – Dennie

+0

Creo que encuentro algo útil con el video, ¡gracias por compartir! – Dennie

1

Me enfrento a este problema también, pero en mi caso usé hilos para buscar las imágenes externas. ¡Es importante que el hilo de ejecución actual no cambie la imagen vista si se reutiliza!

public View getView(int position, View vi, ViewGroup parent) { 
ViewHolder holder; 
String imageUrl = ...; 

if (vi == null) { 
    vi = inflater.inflate(R.layout.tweet, null); 
    holder = new ViewHolder(); 
    holder.image = (ImageView) vi.findViewById(R.id.row_img); 
    ... 
    vi.setTag(holder); 
} else { 
    holder = (ViewHolder) vi.getTag();  
} 
holder.image.setTag(imageUrl); 
... 
DRAW_MANAGER.fetchDrawableOnThread(imageUrl, holder.image); 
} 

Y luego ir a buscar en el hilo que estoy haciendo la importante cheque:

final Handler handler = new Handler() { 
@Override 
public void handleMessage(Message message) { 
    // VERY IMPORTANT CHECK 
    if (urlString.equals(url)) 
     imageView.setImageDrawable((Drawable) message.obj); 
}; 

Thread thread = new Thread() { 

@Override 
public void run() { 
    Drawable drawable = fetchDrawable(urlString); 
    if (drawable != null) { 
     Message message = handler.obtainMessage(1, drawable); 
     handler.sendMessage(message); 
    } 
}}; 
thread.start(); 

Uno también podría cancelar el hilo actual si se vuelve a utilizar su punto de vista (como se describe here), pero decidí no hacerlo porque quiero llenar mi caché para su posterior reutilización.

0

Puede ver el texto de repetición en varias filas si lo maneja de forma incorrecta. Recientemente publiqué un blog sobre este tema: consulte here. Aparte de eso, es posible que desee echar un vistazo a ListView performance optimization. Generalmente se debe a la reutilización de vistas y ya lo he visto varias veces.

1

Solo un consejo: NUNCA use el fondo transparente del diseño del elemento - ralentiza el rendimiento enormemente

Cuestiones relacionadas