Gallery ImageAdapter convertView siempre es nulo
Estoy usando una Galería con un ImageAdapter para cargarlo con ImageViews que extraen imágenes de mis recursos. Mi problema es que el convertView que se pasa al método getView () en mi adaptador es siempre nulo. Esto significa que un nuevo ImageView se crea cada vez que getView () se llama. Esto lleva a horrible preformance porque el GC está funcionando constantemente para borrar todos estos ImageView creados y no más utilizados.
Al parecer, este es un error conocido: el caché de vista de Gallery está roto; Nunca convierte vistas. .
- El niño especificado ya tiene un error de padre en la vista inflado
- Android ScrollView Vs ListView
- Vincular la vista personalizada de Android a una xml de diseño específico (¿es posible?)
- Android: Layout.addView () no funciona
- WebView no se dibuja, WARN / webcore (5336): No se puede obtener la viewWidth después del primer diseño
Mis dos soluciones preferidas son: 1. manejar un caché de vistas en el propio adaptador y cuidar de toda la lógica necesaria para volver a usarlas correctamente. O 2. Incluya una copia personal del widget de Galería e intente arreglarlo para que devuelva correctamente las vistas recicladas.
He comenzado a implementar la opción uno, pero rápidamente me doy cuenta de que no sé exactamente cómo hacer toda la lógica detrás de esa operación. Estoy empezando a pensar que la opción dos podría ser más fácil.
He encontrado el código para el widget Galería aquí: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/widget/Gallery.java
No lo entiendo completamente, pero puedo ver que está llamando
child = mAdapter.getView(position, null, this);
En la línea 745. Mi (tiro en la oscuridad) supongo que esta es la raíz del problema.
¿Alguien tiene experiencia con este error. ¿O puede alguien apuntarme en la dirección correcta para averiguar cómo funciona la situación del reciclador para que pueda ajustar este widget para que funcione correctamente? O incluso sugerir alguna opción alternativa que puede estar pasando por alto.
EDIT: La mejor solución que he encontrado fue una implementación llamada EcoGallery. El único lugar en el que puedo encontrar referencia a él en línea ya está aquí . Para conseguirlo que trabaja usted tiene que poner cada pedazo de allí en el lugar correcto dentro de su proyecto.
- Cambiar / usar múltiples diseños dentro de la misma actividad?
- View getWidth () y getHeight () devuelven 0
- Restaurar la jerarquía de vista desde el estado guardado no restaura las vistas agregadas programaticamente
- Cómo inflar una vista en una posición determinada?
- ¿Cómo ImageView acaba de redibujar parte de su contenido cuando se invoca invalidate (Rect)?
- ¿Cómo varía el tamaño de la instalación de la aplicación en el teléfono?
- Butterknife vs AndroidAnnotations
- ¿Cómo puedo establecer dinámicamente la posición de la vista en Android?
No hay experiencia con ese error en particular, pero he hecho personalizado de almacenamiento en caché antes con un paginador de vista de tercera parte (antes de la lib de soporte).
En realidad no es demasiado difícil honestamente. En mi caso, sabía que habría, como mucho, un elemento en la pantalla. Pero también quería que el elemento a la izquierda y la derecha para ser precargado (se trataba de webs que tira de datos de la red). Así que tengo una serie simple de 3 vistas.
[V1, V2, V3]
Ahora lo único que tiene que hacer es correlacionar una posición en su adaptador a una posición en su caché. Hay una variedad de maneras en que podría abordar esto. Cuando lo pinqué por primera vez, acabo de hacer lo que mi vista actual era ser V2 y girar los elementos de la matriz alrededor al mover el buscapersonas. Así que voltear a la siguiente vista alteraría mi array
[V2, V3, V1]
Era fácil de mantener. O usted podría apenas hacer la matemáticas y calcular una posición a una posición relativa de la memoria caché.
Otro enfoque es crear una cola de entrada, salida. Recicle las vistas empujándolas hacia la cola, y cuando necesite una vista, simplemente haga clic en una de ellas.
No tengo experiencia con el widget de Galería, pero estoy usando mucho ListView con imágenes. De acuerdo con su problema, y el enlace a la cuestión de Google, todavía no han solucionar este problema.
Por lo tanto, hay solutio con una bonita biblioteca (y ejemplos dentro de ella), que solucionan problemas de caché / ajax, y mucho más.
Enlace a la biblioteca
O, más concreto, enlace a ejemplos de imágenes
Si descarga sus ejemplos, encontrará cómo implementaron la galería con el widget Galería, usando su clase de utilidad AQuery en
com.androidquery.test.image.ImageLoadingGalleryActivity
clase.
Extracto del código:
final List<Photo> entries;// here only to show what enteries are... listAq = new AQuery(this); //define as Action class member, here only to show what it is ArrayAdapter<Photo> aa = new ArrayAdapter<Photo>(this, R.layout.gallery_item, entries){ public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null){ convertView = getLayoutInflater().inflate(R.layout.gallery_item, parent, false); } Photo photo = getItem(position); AQuery aq = listAq.recycle(convertView); aq.id(R.id.name).text(photo.title); String tbUrl = photo.tb; if(!aq.shouldDelay(position, convertView, parent, tbUrl)){ aq.id(R.id.tb).image(tbUrl); aq.id(R.id.text).text(photo.title).gone(); }else{ aq.id(R.id.tb).clear(); aq.id(R.id.text).text(photo.title).visible(); } return convertView; } }; aq.id(R.id.gallery).adapter(aa);
Donde la foto es solo objeto POJO (buscado desde el control remoto):
class Photo { String tb; String url; String title; String author; }
R.id.gallery
refiere a
<Gallery android:id="@+id/gallery" android:layout_width="fill_parent" android:layout_height="200dip" />
Y R.layout.gallery_item
refiere a:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="100dip" android:layout_height="75dip" > <ProgressBar android:id="@+id/progress" android:layout_width="15dip" android:layout_height="15dip" android:layout_centerInParent="true" /> <ImageView android:id="@+id/tb" style="@style/GalleryItem" android:layout_width="100dip" android:layout_height="75dip" /> <TextView android:id="@+id/text" android:layout_width="100dip" android:layout_height="75dip" android:gravity="center" android:maxLines="4" android:padding="15dip" android:text="Dummy TextDummy TextDummy TextDummy TextDummy Text" android:textColor="#FFFFFFFF" android:textSize="8sp" /> </RelativeLayout>
Espero que encuentre esta biblioteca útil para resolver su problema.
He conseguido alrededor de esto mediante el uso de una caché personalizada como dskinner sugiere.
Pre-calcule (screenwidth / minwidth del elemento) el número máximo de elementos que se pueden mostrar en la galería en la pantalla a la vez y agregue unos cuantos más (la galería necesitará extra para mostrar elementos a la izquierda ya la derecha cuando usted Desplácese a través de él). Creo una matriz de este tamaño – las vistas se crean según lo solicitado y se colocan en la memoria caché. Utilice la posición% cachesize para determinar qué vista en caché volverá cuando getView se llame.
- ¿Cómo analizar un archivo Android /data/anr/traces.txt?
- Android Support v7 MediaRouter a veces no funciona correctamente