2010-07-07 13 views
8

He leído sobre el tema de getView llamado varias veces y todas las respuestas. Sin embargo, no encuentro una solución para mi problema.Android Adapter multiple getView

Tengo una lista donde las filas tienen dos estados: leer o no. Bueno, quiero que los artículos vistos por primera vez tengan un color diferente y cuando recorro la lista, cambian su color a "estado de lectura".

Para ello, en el método de getView mi adaptador fijo una isRead campo cuando se pinta la fila de ese elemento. Pero el problema es el siguiente: dado que el método getView se llama varias veces, el campo se marca como leído y cuando la lista se muestra en la pantalla, aparece como si ya se hubiera leído.

¿Alguna idea para solucionar este problema?

Gracias

Respuesta

14

Supongo que se refiere al problema de que getView solicite la misma vista varias veces.

ListView hace esto debido a que necesita para obtener mediciones de las vistas para diferentes razones (tamaño de la barra de desplazamiento, de diseño, etc.)

Este problema generalmente se puede evitar al no utilizar la propiedad "wrap_content" en su vista de lista.

Aparte de eso, el uso de getView para determinar si un punto de vista que se ha mostrado es simplemente una mala idea. ListView tiene muchas optimizaciones que desordenan el orden en que se llama a getView para cada fila, por lo que no hay manera de saber qué sucederá y su aplicación comenzará a mostrar un comportamiento extraño.

Trate de evitar cualquier relación entre la vista y los datos que no sean el concepto de vista como una muestra de esos datos.

En su lugar, tienen un poco de hilo trabajador o detector de eventos en su ListActivity ver la lista cuya elementos de la lista se han mostrado al usuario, actualizar los datos, y llamar a dataSetChanged en su adaptador.

+0

"actualizar los datos, y llaman dataSetChanged en el adaptador" - funciona para mí –

0

No es la forma en que desea que funcione. El motivo por el que se llama varias veces al getView() es permitir que el sistema operativo mida las filas para que sepa cómo configurarlas. Debería marcarlo como leído cuando lo presionen o marque una casilla o algo así.

1

tuve el mismo problema y no tenía ninguna referencia en absoluto a "wrap_content" en el attirbute diseños. Aunque este es un hilo viejo, no pude descifrar cómo resolver el problema. Por lo tanto, lo mitigé agregando una lista en el adaptador que contiene las posiciones ya dibujadas, como se muestra en el siguiente código. Creo que no es el momento de hacerlo, pero funcionó para mí.

public class ImageAdapter extends BaseAdapter { 
    private Context mContext; 
    private List<Integer> usedPositions = new ArrayList<Integer>(); 

    public ImageAdapter(Context c, List<String> imageUrls) { 
     mContext = c; 
     ... 
    } 

    ... 

    // create a new ImageView for each item referenced by the Adapter 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imageView; 
     if (convertView == null) { 
      imageView = new ImageView(mContext); 
      imageView.setLayoutParams(new GridView.LayoutParams(85, 85)); 
      imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
      imageView.setPadding(8, 8, 8, 8); 
     } else { 
      imageView = (ImageView) convertView; 
     } 

     if (!usedPositions.contains(position)) { 
      // Your code to fill the imageView object content 
      usedPositions.add(position); // holds the used position 
     } 

     return imageView; 
    } 
} 
0

Aquí hay una forma muy simple de evitar la doble llamada cuando sepa que nada debajo de este bloque de código distorsionará el diseño.

private static List<String> usedPositions = new ArrayList<String>(); 

...

@Override 
public View getView(int position, View rowView, ViewGroup parent) { 
    rowView = inflater.inflate(R.layout.download_listview_item, null); 

    Log.d(LOG_TAG, "--> Position: " + position); 

    if (!usedPositions.contains(String.valueOf(position))){ 
     usedPositions.add(String.valueOf(position)); 
     return rowView; 
    }else{ 
     usedPositions.remove(String.valueOf(position)); 
    } 

...