Berechnen der Höhe jeder Zeile einer ListView

Ich versuche, den Hintergrund eines ListView-Scrolls mit dem ListView zu machen. Ich basiere meinen Ansatz auf diese Klasse in Regalen , aber während in Regalen alles die gleiche Höhe hat, kann ich nicht die gleiche Garantie machen.

Ich habe eine Aktivität wie so:

  • Google Maps aktuelle Positionsmarkierung und Genauigkeit Radius Overlay
  • Native Crash bei /system/lib/libart.so auf lollipop android 5.0.1 samsung
  • Android Appcompat v21 - Verwenden Sie alte Spinner-Stil
  • Holen Sie sich Position von Imageview auf Layout Android
  • Playing HTML5 Video auf Vollbildschirm in Android Webview
  • Android Icon Größen
  • public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView listView = (ListView) findViewById(R.id.listView); List<String> items = new ArrayList<String>(); for(int i=0; i < 100; ++i) { items.add("Hello " + i); } CustomArrayAdapter adapter = new CustomArrayAdapter(this, items); listView.setAdapter(adapter); } } 

    Wo CustomArrayAdapter ist:

     public class CustomArrayAdapter extends ArrayAdapter<String> { private List<Integer> mHeights; public View getView(int position, View convertView, ViewGroup parent) { //snip } } 

    Was ich tun möchte, ist, dass er in den Adapter mit Höhen der Zeilen der Ansicht gedrückt wird.

    Mein Hauptversuch war, dies zu tun, in getView ():

     if(row.getMeasuredHeight() == 0) { row.measure( MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY)); } mHeights.set(position, row.getMeasuredHeight()); 

    Ich habe versucht, mehrere Möglichkeiten, dies zu tun, aber ich kann nichts zu arbeiten.

    In getView , wenn ich getHeight() Ich bekomme einen Rückgabewert von 0, während, wenn ich getMeasuredHeight() bekomme, bekomme ich etwas ungleich Null aber nicht die reale Höhe. Wenn ich nach unten getHeight() == getMeasuredHeight() und dann wieder aufstehe (eine der Zeilen aus der Sicht zu nehmen) getHeight() == getMeasuredHeight() und beide haben den richtigen Wert. Wenn ich nur mHeights in getView aktualisiere, wie ich gehe (indem ich mHeights.set(position, row.getHeight() ), es funktioniert – aber erst nachdem ich an die Unterseite der ListView gescrollt habe. Messen () innerhalb der getView-Methode, aber dies bewirkt getHeight() noch getHeight() zu 0 das erste Mal, wenn es ausgeführt wird.

    Meine Frage ist das: Wie berechne und befolge ich mHeights mit den richtigen Höhen der Zeilen der ListView? Ich habe einige ähnliche Fragen gesehen, aber sie scheinen nicht zu sein, was ich suche. Die ViewTreeObserver Methode scheint vielversprechend zu sein, aber ich kann nicht herausfinden, wie man Anrufe von getView () erzwingen kann (abwechselnd, um die Zeilen der ListView zu iterieren). Aufruf von adapter.notifyDataSetChanged() verursacht eine unendliche (obwohl nicht blockierende) Schleife.

    1. Erhalten Sie tatsächliche Höhe der Ansicht
    2. Wie bekomme ich die Höhe des Artikels in einer Listenansicht?

    Dies hängt mit meiner bisherigen Frage zum Thema zusammen, die den Punkt verpasst hat: ListView Entfernung von oben auf der Liste

  • Unterschiede zwischen ItemizedOverlay und Overlay-Klasse
  • Wie funktioniert das neue FragmentTransaction commitNow () intern?
  • Gradle 14.4 Fehler beim Erstellen - Gradle DSL-Methode nicht gefunden 'packageName ()'
  • Gradientenradius als Prozentsatz der Bildschirmgröße
  • Wie kann ich den Snapshot der Karte aus der Place-Picker-Aktivität abrufen?
  • Tödliches Signal 7 (SIGBUS) bei 0x00000000 (Code = 2)
  • 2 Solutions collect form web for “Berechnen der Höhe jeder Zeile einer ListView”

    Ich habe herausgefunden, wie ich das mache. Es ist ein bisschen knifflig, aber es funktioniert.

    Die Subtilität bekam Layoutparameter, wenn sie bekannt sind. Wie ich gelernt habe, gibt getView() die Ansicht für die anfängliche Zeit zurück, also kann es natürlich noch keine Höhe haben – das Elternteil kennt die Zeile noch nicht (seit es die getView() ist, sie aufzublasen ), Also brauchen wir einen Rückruf.

    Was könnte dieser Rückruf sein? Es stellt sich heraus, so gut ich kann sagen, es ist die OnLayoutChangeListener() für die Zeile der Ansicht. Also in getView() in meinem benutzerdefinierten ArrayAdapter , habe ich einen Rückruf für onLayoutChanged wie ArrayAdapter hinzugefügt:

     row.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { ref.removeOnLayoutChangeListener(this); Log.d("CustomArrayAdapter", "onLayoutChange(" + position + "): height " + (bottom - top)); mHeights.set(position, (bottom - top)); if(position > 0) { mDistances.set(position, bottom - top + mDistances.get(position-1) + ((ListView)parent).getDividerHeight()); } holderRef.distanceFromTop = mDistances.get(position); Log.d("CustomArrayAdapter", "New height for " + position + " is " + mHeights.get(position) + " Distance: " + mDistances.get(position)); } }); 

    Hier ist die row die Ansicht, die von getView() im Adapter zurückgegeben werden soll. mHeights ist eine Liste der Höhe jedes Elements der ListView und mDistances ist eine Liste der Distanz von der Oberseite der ListView in Pixeln – die Echtes Ding, das ich berechnen wollte (das heißt, wenn du die gesamte Listenansicht endet, so weit wie oben vom Top-Element wäre ich von oben). Alle diese werden im benutzerdefinierten ArrayAdapter gespeichert. Diese Listen werden auf Nullen initialisiert.

    Das Hinzufügen dieses Rückrufs erlaubte mir, die Höhe der Ansicht zu berechnen.

    Mein Ziel war es, eine ListView zu haben, die einen Hintergrund hat, der mit der Liste scrollt. Wenn jemand interessiert ist, habe ich den Code auf GitHub gesetzt, wenn jemand es gern überprüfen möchte: https://github.com/mdkess/TexturedListView

    Diese SO-Antwort sollte für Entwickler arbeiten, die auch API Level <11 unterstützen möchten.

    Grundsätzlich können Sie anstelle des Hinzufügens eines View.onLayoutChnageListener zu Ihrer Ansicht einen OnGlobalLayoutListener auf dem OnGlobalLayoutListener Ihrer Ansicht ViewTreeObserver .

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.