2012-03-12 27 views
8

Esta publicación está relacionada con este ViewHolder not working. En esa publicación, estaba siguiendo un tutorial sobre cómo usar ViewHolder en un ListView. Lo que quiero ahora es tener el último elemento en un ListView para tener un diseño diferente al resto. Aquí está mi código:Diferentes diseños de filas en ListView

int lastpos = mList.size()-1; 
      System.out.println("position: "+position+" mlist: "+lastpos); 

      if(position==lastpos){ 
      view = vi.inflate(R.layout.list_item_record, null); 
      holder.textView = (TextView)view.findViewById(R.id.record_view); 
      }else{ 
      view = vi.inflate(R.layout.list_item_bn, null); 
      holder.textView = (TextView)view.findViewById(R.id.tv_name); 
      } 
      view.setTag(holder); 

acabo de obtener el tamaño de menos 1ListView y tener una condición que comprueba la posición actual si es igual al último elemento. Sin embargo, este código establece el diseño del último elemento igual que el resto. getView método código completo:

private class CustomListAdapter extends ArrayAdapter { 
    private ArrayList mList; 
    private Context mContext; 

    public CustomListAdapter(Context context, int textViewResourceId, 
      ArrayList list) { 
     super(context, textViewResourceId, list); 
     this.mList = list; 
     this.mContext = context; 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) { 
     View view = convertView; 

     final ToggleButton tb; 

     if (view == null) { 
      ViewHolder holder = new ViewHolder(); 
      LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

      int lastpos = mList.size()-1; 
      System.out.println("position: "+position+" mlist: "+lastpos); 

      if(position==lastpos){ 
      view = vi.inflate(R.layout.list_item_record, null); 
      holder.textView = (TextView)view.findViewById(R.id.record_view); 
      }else{ 
      view = vi.inflate(R.layout.list_item_bn, null); 
      holder.textView = (TextView)view.findViewById(R.id.tv_name); 
      } 
      view.setTag(holder); 
     } 

     final ItemsDisplay listItem = (ItemsDisplay) mList.get(position); 
      if (listItem != null) { 
      ViewHolder holder1 = (ViewHolder)view.getTag(); 
      holder1.textView.setText(listItem.getTag()); 

      view.setOnClickListener(new OnClickListener() { 
        public void onClick(View arg0) { //--clickOnListItem 
        Toast.makeText(getBaseContext(), 
         "Button is "+position+" "+listItem.getTag(), 
         Toast.LENGTH_LONG).show(); 
        } 
       }); 

       tb = (ToggleButton) view.findViewById(R.id.toggleButton); 
       tb.setOnClickListener(new View.OnClickListener() { 
       public void onClick(View v) { 

       if(tb.isChecked()){ 
       Toast.makeText(getBaseContext(), 
          "Button is "+position+" checked:"+tb.isChecked()+" "+listItem.getTag(), 
          Toast.LENGTH_LONG).show(); 
       }else{ 
       Toast.makeText(getBaseContext(), 
        "Button is "+position+" checked:"+tb.isChecked()+" "+listItem.getTag(), 
          Toast.LENGTH_LONG).show(); 
       } 
       } 
       }); 
      } 



     return view; 
    } 

} 

¿Alguien podría ayudarme con esto?

+1

pegar el código de adaptador completo ... –

+0

añade. ese es el código completo. – antonoVodka

+0

si el ciclo está llamando check like if (...) {Syso ("in if loop")} –

Respuesta

27

implementar el getItemViewType() y getViewTypeCount() para su adaptador:

@Override 
public int getViewTypeCount() { 
    return 2; //return 2, you have two types that the getView() method will return, normal(0) and for the last row(1) 
} 

y:

@Override 
public int getItemViewType(int position) { 
    return (position == this.getCount() - 1) ? 1 : 0; //if we are at the last position then return 1, for any other position return 0 
} 

Luego, en el getView() método de averiguar qué tipo de vista para inflar:

public View getView(final int position, View convertView, ViewGroup parent) { 
     View view = convertView; 
     int theType = getItemViewType(position); 
     if (view == null) { 
      ViewHolder holder = new ViewHolder(); 
      LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      if (theType == 0) { 
       // inflate the ordinary row 
       view = vi.inflate(R.layout.list_item_bn, null); 
       holder.textView = (TextView)view.findViewById(R.id.tv_name);  
      } else if (theType == 1){ 
      // inflate the row for the last position 
       view = vi.inflate(R.layout.list_item_record, null); 
       holder.textView = (TextView)view.findViewById(R.id.record_view); 
      } 
      view.setTag(holder); 
     } 
//other stuff here, keep in mind that you have a different layout for your last position so double check what are trying to initialize 
} 

El ejemplo de los comentarios: http://pastebin.com/gn65240B (o https://gist.github.com/2641914)

+0

intenté esto pero aún no funcionaba. Traté de imprimir el valor de la posición y el Tipo. posición me dio 0-5 solo con theType = 0. ¿porqué es eso? mList consiste en 26 artículos. Me pregunto por qué las posiciones tienen 6 valores solo se oponen a 26 elementos en mi lista. – antonoVodka

+0

@ user1263567 ¿Has desplazado la lista hacia abajo? Creo que es normal obtener solo la posición de 5-6, probablemente porque esta es la posición que se puede ver en la pantalla, sería un desperdicio llamar al método 'getView' para las posiciones que aún no se ven. Si se desplaza por la lista, debería ver las otras posiciones también. – Luksprog

+0

veo. sin embargo, la última fila sigue siendo la misma que el resto. Traté de transferir la última fila a la primera fila, para ver si funciona. funciona, pero cada séptima fila es igual a la primera fila. solo el primero debe ser el único que tenga un diseño diferente al resto. – antonoVodka

0

El problema es que una vez que ha inflado la vista, se puede reutilizar muchas veces en cualquier posición. Sugeriría el siguiente enfoque: se inflan todos los artículos menos el último (incluido el titular de la vista), pero para el último artículo se guarda la referencia como campo de CustomListAdapter y se devuelve cada vez que se solicita el último artículo:

private class CustomListAdapter extends ArrayAdapter { 
    ... 
    private View mLastItem; 

    public View getView(final int position, View convertView, ViewGroup parent) { 
     View view = convertView; 
     ... 
     int lastpos = mList.size()-1; 

     if (view == null) { 
      ViewHolder holder = new ViewHolder(); 
      LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

      if (position == lastpos) { 
       view = vi.inflate(R.layout.list_item_record, null); 
       holder.textView = (TextView)view.findViewById(R.id.record_view); 
       mLastItem = view; 
      } 
      else { 
       view = vi.inflate(R.layout.list_item_bn, null); 
       holder.textView = (TextView)view.findViewById(R.id.tv_name); 
      } 
      view.setTag(holder); 
     } 

     if (position == lastpos) { 
      ... // Update the last item here 
      return mLastItem; 
     } 
     ... 
    } 

} 
+0

esto no funciona demasiado. establece el último elemento con el mismo que el resto. gracias de cualquier forma. – antonoVodka

Cuestiones relacionadas