Ich versuche herauszufinden, wie ich am besten eine einzelne ListView erstellen kann, die unterschiedliche Layouts für jede Zeile enthält. Ich weiß, wie man eine benutzerdefinierte Zeile + einen benutzerdefinierten Array-Adapter erstellt, um eine benutzerdefinierte Zeile für die gesamte Listenansicht zu unterstützen. Wie kann ich jedoch viele verschiedene Zeilenstile in der ListView implementieren?
android
listview
listviewitem
w.donahue
quelle
quelle
Antworten:
Da Sie wissen, wie viele Arten von Layouts Sie haben würden, können Sie diese Methoden verwenden.
getViewTypeCount()
- Diese Methode gibt Informationen darüber zurück, wie viele Zeilentypen Ihre Liste enthältgetItemViewType(int position)
- Gibt Informationen zurück, welchen Layouttyp Sie basierend auf der Position verwenden solltenDann blasen Sie das Layout nur auf, wenn es null ist, und bestimmen den Typ mit
getItemViewType
.Weitere Informationen finden Sie in diesem Tutorial .
Um einige Strukturoptimierungen zu erzielen, die Sie im Kommentar beschrieben haben, würde ich vorschlagen:
ViewHolder
. Dies würde die Geschwindigkeit erhöhen, da Sie nichtfindViewById()
jedes Mal in dergetView
Methode aufrufen müssen . Siehe Liste 14 in API-Demos .Ich hoffe das wird dir helfen. Wenn Sie einen XML-Stub mit Ihrer Datenstruktur und Informationen bereitstellen könnten, wie genau Sie diese in Zeilen abbilden möchten, könnte ich Ihnen genauere Ratschläge geben. Nach Pixel.
quelle
Sie kennen die Grundlagen bereits. Sie benötigen lediglich Ihren benutzerdefinierten Adapter, um basierend auf den bereitgestellten Zeilen- / Cursorinformationen ein anderes Layout / eine andere Ansicht zurückzugeben.
A
ListView
kann mehrere Zeilenstile unterstützen, da es von AdapterView abgeleitet ist :Wenn Sie sich den Adapter ansehen , sehen Sie Methoden, die die Verwendung zeilenspezifischer Ansichten berücksichtigen:
Die beiden letztgenannten Methoden geben die Position an, anhand derer Sie den Ansichtstyp bestimmen können, den Sie für diese Zeile verwenden sollten .
Natürlich verwenden Sie AdapterView und Adapter im Allgemeinen nicht direkt, sondern verwenden oder leiten sie von einer ihrer Unterklassen ab. Die Unterklassen von Adapter können zusätzliche Funktionen hinzufügen, die das Abrufen benutzerdefinierter Layouts für verschiedene Zeilen ändern. Da die für eine bestimmte Zeile verwendete Ansicht vom Adapter gesteuert wird, besteht der Trick darin, den Adapter dazu zu bringen, die gewünschte Ansicht für eine bestimmte Zeile zurückzugeben. Wie das geht, hängt vom jeweiligen Adapter ab.
Um beispielsweise ArrayAdapter zu verwenden ,
getView()
, um die gewünschte Ansicht für die angegebene Position aufzublasen, zu füllen und zurückzugeben. DiegetView()
Methode enthält eine Opportunity-Wiederverwendungsansicht über denconvertView
Parameter.Aber um Derivate von CursorAdapter zu verwenden ,
newView()
, um die gewünschte Ansicht für den aktuellen Cursorstatus (dh die aktuelle "Zeile") aufzublasen, zu füllen und zurückzugeben [Sie müssen auch überschreiben,bindView
damit das Widget Ansichten wiederverwenden kann]Um SimpleCursorAdapter zu verwenden ,
SimpleCursorAdapter.ViewBinder
mit einersetViewValue()
Methode zum Aufblasen, Auffüllen und Zurückgeben der gewünschten Ansicht für eine bestimmte Zeile (aktueller Cursorstatus) und Datenspalte. Die Methode kann nur die "speziellen" Ansichten definieren und auf das Standardverhalten von SimpleCursorAdapter für die "normalen" Bindungen zurückgreifen.Suchen Sie in den spezifischen Beispielen / Tutorials nach der Art des Adapters, den Sie am Ende verwenden.
quelle
BaseAdapter
. Das Ableiten von BaseAdapter wäre am "flexibelsten", aber am schlechtesten bei der Wiederverwendung und Reife von Code, da es das Wissen und die Reife, die bereits in den anderen Adaptern enthalten sind, nicht nutzt.BaseAdapter
gibt es für nicht standardmäßige Kontexte, in denen die anderen Adapter nicht passen.CursorAdapter
undSimpleCursorAdapter
.ArrayAdapter
keine Rolle spielt, welches Layout Sie dem Konstruktor geben, solangegetView()
der richtigegetViewTypeCount()
Anruf nur einmal ausgelöst wirdListView.setAdapter()
, nicht bei jedemAdapter.notifyDataSetChanged()
.Schauen Sie sich den Code unten an.
Zunächst erstellen wir benutzerdefinierte Layouts. In diesem Fall vier Typen.
Even.xml
odd.xml
white.xml
black.xml
Anschließend erstellen wir das Listenansichtselement. In unserem Fall mit einer Zeichenfolge und einem Typ.
Danach erstellen wir einen Ansichtshalter. Es wird dringend empfohlen, da Android OS die Layoutreferenz beibehält, um Ihr Element wiederzuverwenden, wenn es verschwindet und wieder auf dem Bildschirm angezeigt wird. Wenn Sie diesen Ansatz nicht verwenden, erstellt jedes Mal, wenn Ihr Element auf dem Bildschirm des Android-Betriebssystems angezeigt wird, ein neues und Ihre App verliert Speicherplatz.
Schließlich erstellen wir unseren benutzerdefinierten Adapter, der getViewTypeCount () und getItemViewType (int position) überschreibt.
Und unsere Tätigkeit ist ungefähr so:
Erstellen Sie nun eine Listenansicht in mainactivity.xml wie folgt
quelle
In Ihrem benutzerdefinierten Array-Adapter überschreiben Sie die Methode getView (), mit der Sie vermutlich vertraut sind. Anschließend müssen Sie lediglich eine switch-Anweisung oder eine if-Anweisung verwenden, um eine bestimmte benutzerdefinierte Ansicht zurückzugeben, abhängig vom an die getView-Methode übergebenen Positionsargument. Android ist insofern clever, als es Ihnen nur eine ConvertView des für Ihre Position / Zeile geeigneten Typs liefert. Sie müssen nicht überprüfen, ob es vom richtigen Typ ist. Sie können Android dabei helfen, indem Sie die Methoden getItemViewType () und getViewTypeCount () entsprechend überschreiben.
quelle
Wenn in der Listenansicht unterschiedliche Ansichtstypen angezeigt werden müssen, empfiehlt es sich, getViewTypeCount () und getItemViewType () im Adapter zu verwenden, anstatt eine Ansicht umzuschalten. VIEW.GONE und VIEW.VISIBLE können in getView () eine sehr teure Aufgabe sein Auswirkungen auf die Liste scrollen.
Bitte überprüfen Sie dieses für die Verwendung von getViewTypeCount () und getItemViewType () im Adapter.
Link: die Verwendung von getviewtypecount
quelle
ListView war für einfache Anwendungsfälle wie dieselbe statische Ansicht für alle Zeilenelemente gedacht.
Da Sie ViewHolders erstellen und
getItemViewType()
verschiedene XML- Zeilenlayoutlayouts in erheblichem Umfang verwenden und dynamisch anzeigen müssen, sollten Sie dies mit RecyclerView versuchen , das in der Android-API 22 verfügbar ist. Es bietet eine bessere Unterstützung und Struktur für mehrere Ansichtstypen.In diesem Tutorial erfahren Sie, wie Sie mit RecyclerView das tun, wonach Sie suchen.
quelle