Ich habe einen benutzerdefinierten Listenadapter:
class ResultsListAdapter extends ArrayAdapter<RecordItem> {
in der überschriebenen 'getView'-Methode prüfe ich, welche Position ist und ob es sich um eine convertView handelt oder nicht:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("getView " + position + " " + convertView);
Die Ausgabe davon (wenn die Liste zum ersten Mal angezeigt wird, noch keine Benutzereingabe)
04-11 16:24:05.860: INFO/System.out(681): getView 0 null
04-11 16:24:29.020: INFO/System.out(681): getView 1 [email protected]
04-11 16:25:48.070: INFO/System.out(681): getView 2 [email protected]
04-11 16:25:49.110: INFO/System.out(681): getView 3 [email protected]
04-11 16:25:49.710: INFO/System.out(681): getView 0 [email protected]
04-11 16:25:50.251: INFO/System.out(681): getView 1 null
04-11 16:26:01.300: INFO/System.out(681): getView 2 null
04-11 16:26:02.020: INFO/System.out(681): getView 3 null
04-11 16:28:28.091: INFO/System.out(681): getView 0 null
04-11 16:37:46.180: INFO/System.out(681): getView 1 [email protected]
04-11 16:37:47.091: INFO/System.out(681): getView 2 [email protected]
04-11 16:37:47.730: INFO/System.out(681): getView 3 [email protected]
AFAIK, obwohl ich es nicht explizit finden konnte, wird getView () nur für sichtbare Zeilen aufgerufen. Da meine App mit vier sichtbaren Zeilen beginnt, macht zumindest das Positionsnummernwechseln von 0-3 einen Sinn. Aber der Rest ist ein Durcheinander:
Ich habe etwas recherchiert und ohne eine gute Antwort zu erhalten, habe ich bemerkt, dass die Leute dieses Problem mit Layoutproblemen in Verbindung bringen. Für den Fall, hier ist das Layout, das die Liste enthält:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_height="fill_parent"
Android:layout_width="fill_parent"
Android:orientation="vertical" >
<TextView Android:id="@+id/pageDetails"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content" />
<ListView Android:id="@+id/list"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:drawSelectorOnTop="false" />
</LinearLayout>
und das Layout jeder einzelnen Reihe:
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="108dp"
Android:padding="4dp">
<ImageView
Android:id="@+id/thumb"
Android:layout_width="120dp"
Android:layout_height="fill_parent"
Android:layout_alignParentTop="true"
Android:layout_alignParentBottom="true"
Android:layout_alignParentLeft="true"
Android:layout_marginRight="8dp"
Android:src="@drawable/loading" />
<TextView
Android:id="@+id/price"
Android:layout_width="wrap_content"
Android:layout_height="18dp"
Android:layout_toRightOf="@id/thumb"
Android:layout_alignParentBottom="true"
Android:singleLine="true" />
<TextView
Android:id="@+id/date"
Android:layout_width="wrap_content"
Android:layout_height="18dp"
Android:layout_alignParentBottom="true"
Android:layout_alignParentRight="true"
Android:paddingRight="4dp"
Android:singleLine="true" />
<TextView
Android:id="@+id/title"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:textSize="17dp"
Android:layout_toRightOf="@id/thumb"
Android:layout_alignParentRight="true"
Android:layout_alignParentTop="true"
Android:paddingRight="4dp"
Android:layout_alignWithParentIfMissing="true"
Android:gravity="center" />
</RelativeLayout>
Vielen Dank für Ihre Zeit
Dies ist kein Problem, es gibt absolut keine Garantie für die Reihenfolge, in der getView()
aufgerufen wird oder wie oft. In Ihrem speziellen Fall tun Sie mit einer ListView
das Schlimmste, indem Sie einen height=wrap_content
angeben. Dies zwingt ListView
, zum Layout-Zeitpunkt einige Kinder aus dem Adapter heraus zu messen, um zu wissen, wie groß er sein sollte. Dies ist, was ListView
mit der convertViews
versorgt, die an getView()
übergeben wird, sogar bevor Sie einen Bildlauf durchführen.
Versuchen Sie es mit match_parent
in der layout_height
-Eigenschaft der Listenansicht. Dadurch wird verhindert, dass getView()
so oft aufgerufen wird.
Ich habe dieses Problem behoben, als ich sowohl layout_width als auch layout_height in match_parent geändert habe (das Ändern von layout_height half nicht).
Hilfreiche Hinweise Achtung, wenn Sie Objekte verschachtelt haben. Sie müssen das "höchste" in match_parent ändern. Hoffe es hilft jemandem.
Ich kann Ihre "Warum" -Frage nicht beantworten, aber ich habe definitiv eine Lösung für das Problem des irritierenden "ListView-Elements, das" wiederholt (wenn Sie Elemente in Ihrer Sammlung haben, die größer als die Bildschirmhöhe sind).
Wie bereits erwähnt, behalten Sie die Android: layout_height - Eigenschaft des ListVew -Tags als fill_parent.
In Bezug auf die getView () - Funktion besteht die Lösung darin, eine static-Klasse mit dem Namen ViewHolder zu verwenden. Check out das Beispiel. Es führt erfolgreich die Aufgabe aus, alle Elemente in ur Array oder ArrayCollection hinzuzufügen.
Hoffe das hilft Freunden !!
Beste Grüße, Siddhant
Fragen: Warum ruft der Adapter oft getView () auf? Ans: Wenn ListView beim Scrollen rendert, wird die Ansicht mit den nächsten anstehenden Ansichten aktualisiert, beispielsweise für Welcher Adapter benötigt Ansichten, um getView () aufzurufen.
Fragen: Warum werden weniger Anrufe aufgerufen, wenn Breite und Höhe der Listenansicht auf fill_parent eingestellt sind? Ans: Da der Inflator die feste Größe für den Bildschirmbereich für die Liste hat, berechnet er einmal für Rendern der Ansichten auf dem Bildschirm.
Ich hoffe, es wird Ihre Anfrage lösen.
Ich hatte das gleiche Problem mit dem Dropdown in einer AutoCompleteTextView. Ich habe zwei Tage lang mit dem Problem gekämpft, bis ich hier ankomme und Sie mir die Lösung zeigen.
Wenn ich dropDownHeight = "match_parent" schreibe, ist das Problem behoben. Das Problem hängt jetzt mit der Benutzeroberfläche zusammen (wenn Sie einen Eintrag haben, ist die Dropdown-Liste zu groß), aber das Problem mehrerer Anrufe (viel wichtiger) ist behoben.
Vielen Dank!!
Ich habe das gleiche Problem. Wenn ich height auf fill_parent gesetzt habe, dann bekomme ich "normalerweise" 2 Aufrufe pro Zeile. Wenn ich jedoch die Höhe meiner ListView auf den exakten Wert, beispielsweise 300dp, setze, bekomme ich genau einen GetView-Aufruf pro Zeile.
Es scheint mir also, dass der einzige Weg darin besteht, zuerst die Höhe des Bildschirms zu bestimmen und dann die Höhe des Listenwerts auf diesen Wert programmgesteuert einzustellen. Ich mag es nicht Ich hoffe es gibt einen besseren Weg.
"Warum wird getview für jede Zeile dreimal aufgerufen?" Weil getView aufgerufen wird, wenn Sie in der Listenansicht scrollen, und besser gesagt, dass es aufgerufen wird, wenn die Position einer Ansicht Ihrer Liste geändert wird!
Für alle, die noch (nachdem Sie die height
der ListView
auf match_parent
gesetzt haben) festsitzen (wie ich es war):
Sie müssen auch die height
des übergeordneten Layouts auf match_parent
setzen.
Siehe Beispiel unten. Die LinearLayout
ist hier das übergeordnete Element:
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="@string/something" />
<ListView
Android:id="@+id/friendsList"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</LinearLayout>
ich habe diese Lösung gemacht, vielleicht ist sie nicht die beste, aber sie erledigt die Arbeit ...
//initialize control string
private String control_input = " ";
dann =
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View gridview = convertView;
// change input_array for the array you use
if (!control_input.equals(input_array[position])) {
control_input = input_array[position];
//do your magic
}
return gridview;
}
ich hoffe es hilft!
Dies kommt möglicherweise zu spät, aber wenn Sie layout_weight
verwenden, denken Sie daran, layout_width="0dp"
immer einzustellen.