Cómo cargar el ListView "sin problemas" en android
Cargo datos de Cursor a listview, pero mi ListView realmente no mostrar "suave". Los datos cambian cuando arrastre hacia arriba y hacia abajo en el scollbar en mi ListView. Y algunos elementos parecen una pantalla duplicada en mi lista. Tengo un "ListView complejo" (dos textview, una imagen) Así que he utilizado newView (), bindView () para mostrar los datos. ¿Alguien me puede ayudar?
- Snap de vista de lista al elemento
- Cómo utilizar View Holder al tener filas diferentes en un ListView
- ¿Por qué ListView.getCheckedItemPositions () no devuelve valores correctos?
- ¿Por qué (ListView) findViewById devuelve nulo?
- Cómo diseñar Gridview como aplicación guardian
- Cómo expandir una fila de la lista cuando la toquemos en listview
- Cómo puede mostrar un AdView en cada n-ésima posición en un listView
- ListView: ¿Cómo permanecer resaltado / seleccionado después de pulsar el botón Atrás?
- añadir elementos en la parte superior de la vista de lista android
- Cómo deshabilitar vista de encabezado en ListView
- Centralización de diseño de Android en RelativeLayout para ListView personalizado
- Cómo actualizar la lista con el adaptador Cursor
- Android ListView child Ver setEnabled () y setClickable () no hacer nada
Le describiré cómo conseguir tal edición que usted tiene. Posiblemente esto te ayudará.
Así pues, en adaptador de la lista usted tiene tal 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 usted puede ver, fijamos el valor del artículo de la lista solamente después de que hayamos recuperado el sostenedor.
Pero si mueve el código en la sentencia above si:
holder.label.setText(getLabel());
Así que cuidará como abajo:
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); }
Usted tendrá su comportamiento actual de la aplicación con la duplicación del artículo de la lista.
Posiblemente ayudará.
ListView es una bestia complicada.
Su segunda pregunta primero: ve duplicados porque ListView vuelve a usar las vistas a través de convertView, pero no se está cerciorando de restablecer todos los aspectos de la vista convertida. Asegúrese de que la ruta de código para convertView!=null
establece correctamente todos los datos de la vista y todo debería funcionar correctamente.
Usted querrá que su método getView()
se vea más o menos como el siguiente si está usando 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á usando su propia vista personalizada, simplemente reemplace la llamada a new MyCustomView()
con una llamada a inflater.inflate(R.layout.my_layout,null)
En cuanto a su primera pregunta, usted querrá ver el techtalk de Romain en el rendimiento de ListView aquí: http://code.google.com/events/io/sessions/TurboChargeUiAndroidFast.html
De su charla y en orden de importancia de mi propia experiencia,
- Utilizar convertView
- Si tiene imágenes, no escala sus imágenes sobre la marcha. Utilice Bitmap.createScaledBitmap para crear un mapa de bits escalado y poner eso en sus vistas
- Utilice un ViewHolder para que no tenga que llamar a un montón de findViewByIds () cada vez
- Disminuya la complejidad de las vistas en su lista. Cuantas menos subviews, mejor. RelativeLayout es mucho mejor en esto que, digamos, LinearLayout. Y asegúrese de usar si está implementando vistas personalizadas.
Estoy frente a este problema también, pero en mi caso he utilizado hilos para obtener las imágenes externas. ¡Es importante que el hilo de ejecución actual no cambie el imageView si es reutilizado!
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 en el hilo de búsqueda que estoy haciendo la comprobación importante :
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();
También se puede cancelar el subproceso actual si su vista se reutiliza (como se describe aquí ), pero decidí no hacerlo porque quería llenar mi caché para su posterior reutilización.
Sólo un consejo: NUNCA utilice un fondo transparente de diseño de elementos – se ralentiza el rendimiento en gran medida
Puede ver el texto que se repite en varias filas si lo maneja de manera incorrecta. He publicado un blog sobre esto recientemente – ver aquí . Aparte de eso, es posible que desee echar un vistazo a la optimización de rendimiento de ListView . Generalmente es debido a la reutilización de la vista y he visto que pocas veces ya.
- Cómo utilizar el fragmento de diálogo? (ShowDialog obsoleta) Android
- Ancho de navegación de la lista de acciones – envolver contenido