2010-07-08 13 views
8

Tengo un ListView con un adaptador de lista personalizado. En el método getView(), estoy usando el 'patrón' ViewHolder como se muestra en las demostraciones de la API para ListView14.java. Cuando primero aparezco en la lista, parece que se carga correctamente. Sin embargo, el problema al que me estoy enfrentando es que cuando me desplazo por la lista, veo que los datos de la lista aparecen en las filas incorrectas (es decir, aparece un TextView que debería estar en la fila 10 en la fila 2, por ejemplo).) Sin embargo, cuando no uso el viewholder, y en su lugar invoca findViewById() cada vez, la vista de lista se representa correctamente.espectador de vista de lista de Android. cuándo usarlo, y cuándo no a

Respuesta

10

Sin embargo, el problema que estoy corriendo en es que cuando me desplazarse por la lista, estoy ver los datos de la lista mostrará en las filas erróneas (es decir, un TextView que debería estar en la fila 10 aparece en la fila 2, por ejemplo).

Es muy probable que esté reciclando incorrectamente las filas, de modo que ViewHolders que está manipulando no son las correctas para la fila que está devolviendo.

Here is a free excerpt de uno de mis libros que trata sobre el reciclaje de hileras, quizás te ayude a identificar dónde van las cosas mal.

+2

es un gran tutorial, gracias. – eric2323223

1

así que creo que descubrí el verdadero problema aquí. Cuando establece parámetros de diseño sobre la marcha para cada fila, debe asegurarse de hacerlo en todas las condiciones. mi problema era que si era la primera fila, configuré un param de diseño (como relleno o márgenes, etc.), pero si era una fila del medio, no establecía explícitamente esos parámetros pensando que solo usaría lo que estaba inflado. por la vista inflater. Esto explica por qué funcionó cuando inflaba la vista cada vez. Aquí es un antes & después:

ANTES:

if (position == 0) { 

      layoutParams.topMargin = uiHelper.getDip(15.0f); 
      layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 
        RelativeLayout.TRUE); 
      holder.actionMenu.setLayoutParams(layoutParams); 

      holder.contentLayout.setBackgroundResource(R.drawable.top_row); 

     } else if (position == posts.size() - 1) { 
      holder.contentLayout 
        .setBackgroundResource(R.drawable.bottom_row); 

      holder.contentLayout.setPadding(holder.contentLayout 
        .getPaddingLeft(), 
        holder.contentLayout.getPaddingTop(), 
        holder.contentLayout.getPaddingRight(), 
        holder.contentLayout.getPaddingBottom() + uiHelper.getDip(10.0f)); 

     } else { 
      holder.contentLayout 
        .setBackgroundResource(R.drawable.inner_row); 
     } 

DESPUÉS: `

  layoutParams.topMargin = uiHelper.getDip(10.0f); 
     holder.contentLayout.setPadding(holder.contentLayout 
       .getPaddingLeft(), 
       holder.contentLayout.getPaddingTop(), 
       holder.contentLayout.getPaddingRight(), 
       uiHelper.getDip(10.0f)); 
     if (position == 0) { 

      layoutParams.topMargin = uiHelper.getDip(15.0f); 
      layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 
        RelativeLayout.TRUE); 

      holder.contentLayout.setBackgroundResource(R.drawable.top_row); 

     } else if (position == posts.size() - 1) { 
      holder.contentLayout 
        .setBackgroundResource(R.drawable.bottom_row); 

      holder.contentLayout.setPadding(holder.contentLayout 
        .getPaddingLeft(), 
        holder.contentLayout.getPaddingTop(), 
        holder.contentLayout.getPaddingRight(), 
        uiHelper.getDip(20.0f)); 

     } else { 

      holder.contentLayout 
        .setBackgroundResource(R.drawable.inner_row); 

     } 

     holder.actionMenu.setLayoutParams(layoutParams); 
2
  • me enfrentaba mismo problema
  • Resuelto mediante el siguiente techninc
  • Motivo: no adaptador Cargado Frequentlyy.
  • en su clase de adaptador de encargo añade ViewHolder usando el acceso especificadores

    private static class ViewHolder { 
    
         protected TextView itemName; 
    
        } 
    

En Obtener vista método

@Override 

     public View getView(int position, View view, ViewGroup viewGroup) { 

      // create a ViewHolder reference 
      ViewHolder holder; 

      //check to see if the reused view is null or not, if is not null then reuse it 
      if (view == null) { 
       holder = new ViewHolder(); 

       view = mLayoutInflater.inflate(R.layout.list_item, null); 
       holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view); 

       // the setTag is used to store the data within this view 
       view.setTag(holder); 
      } else { 
       // the getTag returns the viewHolder object set as a tag to the view 
       holder = (ViewHolder)view.getTag(); 
      } 
    // now Use Holder object toget Idss 

    holder.itemName.setText(" sample text based on position "); 
    } 

Importante: y no debemos establecer cualquier etiqueta para la vista objeto excepto Viewholder Object

+0

Muchas gracias por este útil fragmento de código. – swiftBoy

Cuestiones relacionadas