2014-09-22 9 views
10

Ho uno snippet di codice semplice per implementare listview personalizzato.Qual è il funzionamento di setTag e getTag nel pattern ViewHolder?

Il mio codice è il seguente:

WeatherAdapter.java:

public class WeatherAdapter extends ArrayAdapter<weather>{ 

    Context mcontext; 
    int mlayoutResourceId;  
    weather mdata[] = null; 
    View row; 

    public WeatherAdapter(Context context, int layoutResourceId, weather[] data) { 
     super(context, layoutResourceId, data); 
     mlayoutResourceId = layoutResourceId; 
     mcontext = context; 
     mdata = data; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     row = convertView; 
     WeatherHolder holder = null; 

     if(row == null) 
     { 
      LayoutInflater inflater = ((Activity) mcontext).getLayoutInflater(); 
      row = inflater.inflate(mlayoutResourceId, parent, false); 

      holder = new WeatherHolder(row); 


      row.setTag(holder); 

     } 
     else 
     { 
      holder = (WeatherHolder)row.getTag(); 
     } 

     weather w = mdata[position]; 
     holder.txtTitle.setText(w.mtitle); 
     holder.imgIcon.setImageResource(w.micon); 

     return row; 
    } 

WeatherHolder.java:

class WeatherHolder 
    { 
     ImageView imgIcon; 
     TextView txtTitle; 


    public WeatherHolder(View v){ 

      imgIcon = (ImageView)row.findViewById(R.id.imgIcon); 
      txtTitle = (TextView)row.findViewById(R.id.txtTitle); 

    } 
    } 
} 

ho visto così tante risposte su SO e altre siti e ho capito il meccanismo di riciclaggio di listview.

Ho anche capito che dal viewholder, possiamo contenere le visualizzazioni figlio nell'adattatore e non dobbiamo chiamare più volte findViewById(). Quindi, è per l'ottimizzazione.

Ma ho solo la confusione nei metodi setTag(holder) e getTag(). From this question, sono venuto a sapere che è per fare una coppia chiave-valore su più oggetti, in modo che possiamo accedervi facilmente. Ma non capisco perché siano richiesti qui ... perché non abbiamo più oggetti titolare ... solo dobbiamo cambiare le variabili del titolare ogni volta. possiamo codificare qui senza utilizzare setTag e getTag?

qualcuno può spiegare meglio che cosa fanno "qui" setTag e getTag?

+0

per favore non contrassegnare come duplicato ... Ho visto tante risposte ma non ho trovato il giusto per una situazione particolare. – xyz

+1

perché non provare a modo tuo e vedere qual è il risultato? – panini

+0

Ho già provato ... Non ho fatto domande senza alcun tentativo ... Se sai, allora ti preghiamo di dare la risposta – xyz

risposta

21

tag è un meccanismo per rendere il vostro views ricordare qualcosa, che potrebbe essere un object un integer un string o qualcosa che ti piace.

in modo che quando il tuo ListView sta per creare per la prima volta il tuo convertView è null. così si crea un nuovo convertView e mettere tutta la vostra references della objects di che row in un viewHolder. quindi salva il tuo viewHolder nella memoria di quello convertView (setTag). Android prende il tuo convertView e lo mette nella sua pool per recycle e passes di nuovo per voi. ma il suo pool potrebbe non avere abbastanza convertViews quindi passa nuovamente un nuovo . quindi, di nuovo, la storia viene ripetuta fino a quando lo pool di android viene riempito. dopo di che android prende un convertView dal suo pool e lo passa a te. troverai che non è null quindi ti chiedi dove sono il mio oggetto references che ti ho dato per la prima volta? (getTag) così otterrai quelli e fai quello che vuoi.

Altro elaborazione on line sotto

but its pool may not have enough convertViews so it again passes a new convertView thats null

Android pool è vuoto quando il listView sta per creare. quindi per il primo articolo del tuo listView ti viene inviato uno convertView che deve essere visualizzato. dopo di che android lo salva nel suo pool, quindi il suo pool ora contiene solo uno convertView. per il tuo secondo elemento del tuo listView che sta per creare Android non puoi utilizzare il suo pool perché in realtà ha un elemento e quell'elemento è il tuo primo oggetto e viene mostrato in questo momento in modo che debba passare un altro convertView. questo processo si ripete fino al android trovato un convertView nel suo pool che non viene visualizzato ora e lo passa a voi.

Android si gonfia ogni riga fino a quando lo schermo si riempie dopo che si scorre l'elenco che utilizza il titolare.

+0

grazie, ma non riesco a capire questo: "ma il suo pool potrebbe non avere abbastanza convertViews quindi passa nuovamente un nuovo convertView che è nullo" - allora in quale situazione, potrebbe non avere abbastanza visualizzazioni di conversione? – xyz

+0

aggiornalo guarda di nuovo – mmlooloo

+0

grazie ...In breve, Android deve gonfiare il layout della nuova riga fino a quando il layout non si adatta alle dimensioni dello schermo. dopo che utilizza il titolare per modificare le visualizzazioni figlio all'interno della riga. destra? – xyz

2

Ma, non capisco il motivo per cui sono tenuti qui ... perché, non abbiamo supporto più oggetti

Questo è dove si è sbagliato - v'è un supporto per view (aka voce ListView visibile o memorizzata nella cache).

+0

puoi spiegarmi più dettagliatamente? – xyz

+1

C'è un "supporto WeatherHolder" separato per ogni vista. –

+0

@ShivamVerma volevi dire - per ogni riga. destra? – xyz

14

consente di guardare in una prospettiva diversa:

enter image description here

lascia immaginare che il elicottero è il "fila", mentre il corda è il "setTag" e la macchina di seguito è "WeatherHolder", ma il pilota dell'elicottero è all'interno di quella macchina e lui/lei l'unico controllo Imbracare l'elicottero usando un "REMOTE CABLATO".

Quando si taglia la corda che è "setTag", l'Hellicopter vola ancora ma il pilota non può più controllarlo poiché il pilota è a terra, il che significa che il pilota è morto! (In java quando un oggetto perde il suo riferimento, il Garbage Collector lo raccoglierà e lo libererà dalla memoria).

Quando non si posiziona o si fissa la fune all'auto mentre l'elicottero sta per volare dove è seduto il pilota, si può potenzialmente perdere un controllo sull'elicottero perché si utilizza "REMOTE CABLATO".

Spero che questo aiuto :).

Problemi correlati