8

Questo post è correlato a questo ViewHolder not working. In quel post, stavo seguendo un tutorial su come utilizzare ViewHolder su un ListView. Quello che voglio ora è di avere l'ultimo elemento su un ListView per avere un layout diverso rispetto al resto. Qui è il mio codice:Layout di righe differenti in 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); 

Ho appena ottenere la dimensione meno 1ListView e avere una condizione che controlla la posizione corrente, se è uguale a l'ultimo elemento. Tuttavia, questo codice imposta il layout dell'ultimo elemento come il resto. getView metodo di codice 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; 
    } 

} 

Qualcuno potrebbe aiutarmi con questo?

+1

incollare il codice adattatore pieno ... –

+0

aggiunto. questo è il codice completo. – antonoVodka

+0

se il loop sta chiamando check come se (...) {Syso ("in if loop")} –

risposta

27

Implementare la getItemViewType() e getViewTypeCount() per l'adattatore:

@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) 
} 

e:

@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 
} 

Poi nel getView() metodo di scoprire che tipo di vista per gonfiare:

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 
} 

L'esempio dai commenti: http://pastebin.com/gn65240B (o https://gist.github.com/2641914)

+0

ho provato questo ma ancora non funziona. ho provato a stampare il valore di position e theType. posizione mi ha dato 0-5 solo con theType = 0. perché? mList composto da 26 articoli. mi sto solo chiedendo perché le posizioni hanno 6 valori che si oppongono solo a 26 elementi sulla mia lista. – antonoVodka

+0

@ user1263567 Hai fatto scorrere l'elenco verso il basso? Penso che sia normale ottenere solo la posizione 5-6, probabilmente perché questa è la posizione che può essere vista sullo schermo, sarebbe uno spreco chiamare il metodo 'getView' per le posizioni che non sono ancora viste. Se scorri la lista dovresti vedere anche le altre posizioni. – Luksprog

+0

vedo. tuttavia, l'ultima riga è sempre la stessa del resto. ho provato a trasferire l'ultima riga alla prima riga, per vedere se funziona. Funziona ma ogni 7 ° fila è uguale alla prima riga. solo il primo dovrebbe essere l'unico ad avere un layout diverso rispetto al resto. – antonoVodka

0

Il problema è che una volta ingrandita la vista può essere riutilizzata più volte in qualsiasi posizione. Suggerisco il seguente approccio: si gonfia tutto tranne l'ultimo oggetto come al solito (incluso il titolare della vista), ma per l'ultimo elemento si tiene il riferimento come un campo di CustomListAdapter e lo si restituisce ogni volta che viene richiesto l'ultimo elemento:

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

anche questo non funziona. imposta l'ultimo elemento uguale al resto. grazie comunque. – antonoVodka

Problemi correlati