2011-10-11 12 views
14

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 siempre es nulo. Esto significa que se crea un nuevo ImageView cada vez que se llama a getView(). Esto conduce a un rendimiento horrible porque el GC se ejecuta constantemente para eliminar todos estos ImageView creados y que ya no se usan.Gallery ImageAdapter convertView siempre es nulo

Esto es aparentemente un error conocido: Gallery's view cache is broken; never converts views..

Mis dos soluciones preferidas son 1. manejar un caché de vistas en el adaptador y ocuparme de toda la lógica necesaria para volver a utilizarlas correctamente. o 2. incluir una copia del widget de la Galería e intentar solucionarlo para que devuelva correctamente las vistas recicladas.

Comencé a implementar la opción uno, pero me doy cuenta rápidamente 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 entiendo completamente, pero puedo ver que está llamando

child = mAdapter.getView(position, null, this); 

en la línea 745. Mi (disparado en la oscuridad) adivina que esta es la raíz del problema.

¿Alguien tiene experiencia con este error. ¿O puede alguien señalarme 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 pueda estar pasando por alto.

EDIT: La mejor solución que he encontrado fue una implementación llamada EcoGallery. El único lugar donde puedo encontrar referencia es online anymore is here. Para que funcione, debes colocar cada fragmento en el lugar correcto dentro de tu proyecto.

+0

Mayo Ayuda http://stackoverflow.com/questions/10769989/how-do-i-get-the-selected-item-from-a-gridview-with-imageadapter-android –

Respuesta

3

No tengo ninguna experiencia con ese error en particular, pero he hecho un caché personalizado antes con un paginador de vista de terceros (antes de la lib de soporte).

Realmente no es demasiado difícil con honestidad. En mi caso, sabía que habría, como máximo, un elemento en la pantalla. Pero también quería que el elemento a la izquierda y a la derecha fuera precargado (se trataba de webviews que extraían datos de la red). Entonces tengo una matriz simple de 3 vistas.

[V1, V2, V3] 

Ahora lo único que debe hacer es correlacionar una posición en su adaptador a una posición en su caché. Hay una variedad de formas en que puedes abordar esto. La primera vez que lo amplifiqué, simplemente hice que mi vista actual fuera V2 y giré los elementos de la matriz cuando volteé el busca. Así que voltear a la siguiente vista alteraría mi matriz

[V2, V3, V1] 

Era fácil de seguir. O simplemente puede hacer los cálculos y calcular una posición en una posición relativa de la memoria caché.

Otro enfoque es crear una cola de último en entrar, primero en salir. Recicle las vistas empujándolas a la cola, y cuando necesite una vista, solo saque una de ellas.

+0

Lo intenté por un tiempo con el objeto Queue para mantener las vistas para mí. Nunca tengo trabajo, pero estoy de acuerdo que se puede hacer de esa manera =) – FoamyGuy

+0

utilizar una matriz vistas a la memoria caché la vista, y 'cachePos% VIEW_CACHE_SIZE' – shaobin0604

1

No tengo experiencia con el widget Galería, pero estoy usando mucho ListView con imágenes.De acuerdo con su problema, y ​​el vínculo al problema de Google, todavía no han solucionado este problema.

Por lo tanto, hay una solución con buena biblioteca (y ejemplos dentro de ella), que resuelven problemas de caché/ajax, y mucho más.

Enlace a library

o, más concreto, un enlace a la imagen examples

Si descarga sus ejemplos, se encuentra la forma en que implementan galería con galería de widgets, utilizando su clase de utilidad AQuery en

com.androidquery.test.image.ImageLoadingGalleryActivity clase.

de fragmentos de 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); 

Cuando la foto es simplemente objeto POJO (obtienen de distancia):

class Photo { 
    String tb; 
    String url; 
    String title; 
    String author; 
} 

R.id.gallery se refiere a

<Gallery 
     android:id="@+id/gallery" 
     android:layout_width="fill_parent" 
     android:layout_height="200dip" /> 

Y R.layout.gallery_item se 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 esta biblioteca le resulte útil para resolver su problema.

0

he conseguido evitar esto mediante el uso de un caché personalizado como dskinner sugiere.

Precalculo (ancho de pantalla/min ancho de elemento) la cantidad máxima de elementos que se pueden mostrar en la galería en la pantalla a la vez y agregue algunos más (la galería necesitará más para mostrar los elementos de la izquierda y justo cuando te desplazas por él). Creo una matriz de este tamaño: las vistas se crean según lo solicitado y se colocan en la caché. Use la posición% de tamaño de caché para determinar qué vista en caché devolver cuando se llama a getView.

+0

un pequeño ejemplo de código = posición, o un enlace a un cierto código/GIST haría ayuda mucho aquí – iwein

Cuestiones relacionadas