Monodroid - Handhabung Klicken Sie auf Ereignisse in ListAdapter-Zeilen

9

Ich habe eine ListView mit einem ArrayAdapter, und jede Zeile im Adapter enthält vier Schaltflächen, die Klickereignisse empfangen und verarbeiten müssen. Normalerweise würde ich bei der Erstellung der Zelle SetOnClickListener auf jeder Schaltfläche aufrufen, aber Mono bietet stattdessen die Möglichkeit, Ereignishandler für das Ereignis Click zu setzen. Es sieht jedoch so aus, als gäbe es in Mono etwas Seltsames, weil ich je nachdem, wo ich den Event-Handler eingestellt habe, auf eines der beiden Probleme stoße.

ArrayAdapter GetView Beispiel 1:

%Vor%

Hier wird mein Event-Handler nur einmal pro Button gesetzt (gut!), aber der position -Wert ist meistens falsch. Ich frage mich, ob die Konvertierung von Mono zu Android-Code bewirkt, dass GetItem(position) immer den gleichen Wert für position verwendet (der Wert, auf den position gesetzt wird, wenn die Zelle zum ersten Mal erstellt wird). Dieser Code würde im normalen Android völlig funktionieren.

ArrayAdapter GetView Beispiel 2:

%Vor%

Diese Methode bewirkt, dass das click -Ereignis für die korrekte position ausgelöst wird, setzt jedoch bei jeder Wiederverwendung der Zeile einen neuen Ereignishandler. Dies führt zu Klick-Ereignissen für viele Zeilen gleichzeitig. Eine Problemumgehung für diese Methode scheint darin zu bestehen, Referenzen auf die Event-Handler zu behalten und sie zu entfernen, bevor sie in GetView erneut gesetzt werden, aber das scheint extrem unelegant zu sein.

Gibt es eine bessere Methode zur Handhabung von Klickereignissen in ListView-Elementen in Monodroid?

    
BigFwoosh 25.04.2013, 13:11
quelle

3 Antworten

1

Ich weiß, es ist ein alter Thread, aber es hat viele Stimmen und ist immer noch als unbeantwortet markiert.

Es ist nur logisch, dass die von Ihnen beschriebenen Szenarien passieren! Es hat nichts mit Mono zu tun. Es hat mit dem Conversionview zu tun. Dies ist, was die Dokumentation in convertview sagt:

  

convertView - Die alte Ansicht zur Wiederverwendung, wenn möglich. Hinweis: Sie sollten   Überprüfen Sie, ob diese Ansicht nicht null und von einem geeigneten Typ ist   verwenden. Wenn es nicht möglich ist, diese Ansicht zu konvertieren, um die   Korrekte Daten, diese Methode kann eine neue Ansicht erstellen.

Beispiel 1: In Ihrem ersten Beispiel wird convertView beim ersten Mal null sein und die Ereignisse werden gesetzt. Dann, wenn die Methode GetView das nächste Mal aufgerufen wird, kann Convertview null sein oder nicht. Wenn es nicht null ist, wird es die alte Ansicht mit den noch angehängten Ereignissen verwenden! Das bedeutet also, dass das Ereignis mit dem Positionsparameter noch aus einer vorherigen Ansicht stammt!

Beispiel 2: Dieses Beispiel wird wie erwartet funktionieren, aber es ist nicht sehr effizient, wie Sie erwähnt haben. Es muss die Steuerelemente jedes Mal suchen, wenn die FindViewById -Methode aufgerufen wird.

Lösung: Die Lösung für dieses Leistungsproblem besteht darin, das Viewholder-Muster zu implementieren.

Zuerst erstellen Sie eine Klasse, die Ihre Ansichten enthält:

%Vor%

Jetzt können Sie diesen Viewholder in Ihrem Code verwenden

%Vor%

Weitere Informationen zu diesem Check-out: Ссылка

    
Marc Bruins 05.04.2016 07:12
quelle
0

Ich hatte auch ähnliche Probleme. Anscheinend werde ich Lösung 2 vermeiden. Außerdem beobachte ich das Problem in Lösung 1 nur bei Android 2.3.

So habe ich das Problem behoben.

Ich behalte einen Verweis auf die ListView im Adapter, sagen wir _listView . Dann, in Ihrer GetItem() -Methode (Verpassen Sie nicht die Variable position . Ihr Wert ist ein Mysterium), rufen Sie _listView.GetPositionForView((View)sender) auf, um die richtige Position zu erhalten.

    
Aaron He 25.04.2013 19:01
quelle
0

Versuchen Sie es mit diesem Code:

%Vor%     
StefanoM5 02.10.2014 09:26
quelle