2014-09-22 10 views
10

Ich habe ein einfaches Code-Snippet für die Implementierung von benutzerdefinierten Listview.Was ist die Arbeit von SetTag und getTag im ViewHolder-Muster?

Mein Code ist wie folgt:

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); 

    } 
    } 
} 

Ich habe so viele Antworten gesehen auf SO und andere Websites und ich verstanden den Recycling-Mechanismus von Listview.

Ich habe auch verstanden, dass von Viewholder, können wir die Kind Ansichten in den Adapter halten und wir müssen findViewById() viele Male nicht aufrufen. Also, es ist für die Optimierung.

Aber ich habe nur die Verwirrung in setTag(holder) und getTag() Methoden. From this question, habe ich erfahren, dass es ein Schlüssel-Wert-Paar für mehrere Objekte ist, so dass wir leicht darauf zugreifen können. Aber ich verstehe nicht, warum sie hier benötigt werden ... weil wir nicht mehrere Halterobjekte haben ... nur müssen wir die Variablen des Halters jedes Mal ändern. können wir hier ohne setTag und getTag programmieren?

kann jemand besser erklären, was setTag und getTag tun "hier"?

+0

Bitte nicht als Duplikat markieren ... Ich habe so viele Antworten gesehen, konnte aber nicht das richtige für eine bestimmte Situation finden. – xyz

+1

warum nicht versuchen Sie es auf Ihre Weise und sehen, was das Ergebnis ist? – panini

+0

Ich habe es bereits versucht ... Ich habe keine Frage gestellt, ohne jeden Versuch..Wenn Sie wissen, dann geben Sie bitte die Antwort – xyz

Antwort

21

tag ist ein Mechanismus, Ihre views erinnern sich an etwas zu machen, dass ein object ein integer ein string oder alles, was Sie gerne sein könnte.

also wenn Ihre ListView wird zum ersten Mal erstellen Ihre convertView ist null. so erstellen Sie eine neue convertView und setzen Sie alle Ihre references der objects dieser row in eine viewHolder. dann speichern Sie Ihre viewHolder in den Speicher dieser convertView (setTag). Android nimmt Ihre convertView und steckt sie in seine pool zu recycle es und passes es wieder für Sie. aber seine pool kann nicht genug convertViews haben, so dass es wieder eine neue convertView Thats null passiert. So wird die Geschichte wiederholt, bis die pool von android aufgefüllt ist. danach nimmt android einen convertView aus seinem Pool und übergibt es Ihnen. Sie werden feststellen, dass es nicht null ist, so dass Sie fragen, wo sind meine Objekte references, die ich Ihnen zum ersten Mal gegeben habe? (getTag) also werden Sie diejenigen bekommen und tun, was auch immer Sie mögen.

Weitere Ausführungen zu unterhalb der Linie

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

android pool ist leer, wenn Ihr listView erstellen wird. Also für den ersten Artikel Ihrer listView sendet es Ihnen eine convertView, die angezeigt werden muss. danach speichert android es in seiner pool, so dass seine pool jetzt nur noch eine convertView enthält. für Ihren zweiten Artikel Ihrer listView, die Android erstellen wird, kann nicht seinen Pool verwenden, weil es tatsächlich ein Element hat und dieses Element ist Ihr erstes Element und es wird gerade angezeigt, so dass es eine andere convertView passieren muss. Dieser Vorgang wiederholt sich, bis android in seinem convertView gefunden wird, das jetzt nicht angezeigt wird und es an Sie weitergibt.

Android bläst jede Zeile auf, bis der Bildschirm danach ausgefüllt ist, wenn Sie in der Liste blättern, die er verwendet.

+0

danke, aber ich konnte das nicht verstehen: "aber sein Pool hat möglicherweise nicht genug convertViews, so dass es wieder ein neues convertView gibt, das null ist" - dann, in welcher Situation, kann es nicht genug convertviews haben? – xyz

+0

aktualisieren sie es wieder schauen – mmlooloo

+0

danke ...Kurz gesagt, Android muss das Layout der neuen Zeile aufblasen, bis das Layout der Bildschirmgröße entspricht. Danach wird der Halter verwendet, um die untergeordneten Ansichten innerhalb der Zeile zu ändern. Recht? – xyz

2

Aber ich verstehe nicht, warum sie hier erforderlich sind, ... weil wir nicht mehrere Inhaber haben Objekte

Dies ist, wo Sie sind falsch - es ist ein Halter-per-View (auch bekannt als sichtbarer oder im Cache gespeicherter ListView-Eintrag).

+0

können Sie ausführlicher erklären? – xyz

+1

Für jede Ansicht gibt es einen separaten "WeatherHolder-Halter". –

+0

@ShivamVerma meinst du - für jede Zeile. Recht? – xyz

14

Hier können in einer anderen Perspektive betrachten:

enter image description here

Lässt sich vorstellen, dass die Hubschrauber die "Reihe" ist, während die Seil die "setTag" ist und die Auto unten ist "WeatherHolder", aber der Pilot des Helikopters ist in diesem Auto und er/sie der eine Managing Contro llen Sie den Helikopter mit einer "WIRED REMOTE".

Wenn du das Seil durchschneidest, was "setTag" ist, fliege der Hellicopter immer noch, aber der Pilot kann es nicht mehr kontrollieren, da der Pilot in den Boden fällt, was bedeutet, dass der Pilot jetzt tot ist! (In Java, wenn ein Objekt seine Referenz verliert, wird der Garbage Collector dies erfassen und aus dem Speicher entfernen).

Wenn Sie das Seil nicht an das Auto legen oder befestigen, während der Helikopter gerade dort fliegt, wo der Pilot sitzt, verlieren Sie möglicherweise die Kontrolle über den Helikopter, da Sie "WIRED REMOTE" verwenden.

Ich hoffe diese Hilfe :).