Ich möchte eine Liste von etwa 200 ImageViews (zufällige Höhen) mit dem folgenden Layout in einer Collage erstellen:
Normalerweise würde ich dies in einem ListView für die Leistung machen, die ich mit Adaptern erhalte, aber da ich möchte, dass die Bilder in Spalten und mit unterschiedlicher Höhe angezeigt werden (Siehe Bild Beispiel ) abhängig von den Bildern kann ich zu diesem Zweck keine einzige Listenansicht verwenden.
Ich habe versucht, dieses Layout mit:
zu implementierenIch habe drei LinearLayouts in einer ScrollView verwendet, aber das ist alles andere als optimal. Ich würde lieber etwas mit einem Adapter verwenden.
BEARBEITEN Ich habe mir die StaggeredGridView angesehen, wie in einer Antwort unten, aber ich finde es ziemlich fehlerhaft. Gibt es stabilere Implementierungen?
Ich denke, ich habe eine funktionierende Lösung für Sie.
Die hier erwähnten Hauptdateien befinden sich auch auf PasteBin in Ссылка
Ich habe im Grunde ein vereinfachtes Äquivalent des erwähnten github-Projekts implementiert, Ссылка , mit einer Reihe von exzellenten LoopJ SmartImageViews
.
Meine Lösung ist bei weitem nicht so generisch und flexibel wie die StaggeredGridView
, scheint aber gut und schnell zu funktionieren. Ein großer Unterschied funktional ist, dass wir die Bilder immer nur von links nach rechts, dann von links nach rechts wieder anordnen. Wir versuchen nicht, das nächste Bild in die kürzeste Spalte zu stellen. Dies macht die Unterseite der Ansicht ein wenig unebener, erzeugt jedoch weniger Verschiebung während der anfänglichen Belastung von der Bahn.
Es gibt drei Hauptklassen, eine benutzerdefinierte StagScrollView
, die eine benutzerdefinierte StagLayout
(untergeordnete Klasse FrameLayout
) enthält, die eine Gruppe von ImageInfo
-Datenobjekten verwaltet.
Hier ist unser Layout , stag_layout.xml ( die anfängliche Höhe von 1000 dpi ist irrelevant, da sie im Code basierend auf den Bildgrößen neu berechnet wird ):
%Vor% Hier ist unsere Aktivität onCreate
, die das Layout verwendet. Die StagActivity
sagt im Grunde nur die StagLayout
welche URLs zu verwenden sind, wie groß der Abstand zwischen jedem Bild sein soll und wie viele Spalten es gibt. Für mehr Modularität hätten wir diese Parameter an die StagScrollView übergeben können (die das StagLayout enthält, aber die Bildlaufansicht hätte sie sowieso nur durch das Layout führen müssen):
Bevor wir zu der Lösung kommen, ist hier unsere einfache StagScrollView
Unterklasse. Sein einziges spezielles Verhalten ist es, seinem Hauptkind (unserem StagLayout
) zu sagen, welches der aktuell sichtbare Bereich ist, damit er die kleinstmögliche Anzahl von realisierten Untersichten effizient nutzen kann.
Hier ist dann die wichtigste Klasse StagLayout
.
Zuerst richtet setUrls
unsere Datenstrukturen ein.
Unsere Hauptdatenstruktur ist ImageInfo
. Es ist eine Art leichter Platzhalter, mit dem wir verfolgen können, wo jedes Bild angezeigt wird, wenn es sein muss. Wenn wir unsere untergeordneten Ansichten planen, verwenden wir die Informationen in ImageInfo, um herauszufinden, wo die tatsächliche Ansicht platziert werden soll. Eine gute Möglichkeit, über ImageInfo nachzudenken, ist eine "virtuelle Bildansicht".
Siehe inline für Details.
%Vor% Der Rest der Magie passiert in StagLayout's
onMeasure
und onLayout
.
Ok, jetzt sehen wir, wie wir alle ImageInfos organisieren.
%Vor% Und jetzt sehen wir, wie wir reale SmartImageViews
während onLayout
erstellen, wiederverwenden und entsorgen.
Denken Sie daran, dass _viewportTop und _viewportBottom bei jedem Scrollen des Benutzers festgelegt werden.
%Vor%Sie können sich Ссылка
ansehenIch habe nicht persönlich daran gearbeitet, aber Sie könnten zumindest einige Konzepte stehlen.
Hoffe, das hilft!
Ich denke, es kann mit drei unabhängigen Listenansicht implementiert werden, nur was Sie tun müssen, um Layout für Bildansicht aufzublasen und es zu Listview hinzuzufügen.
Verwenden Sie folgende Parameter als Layout beim Aufpumpen.
Layoutbreite: match_parent Layout Höhe: wrap_content Sie können das Layoutgewicht als .3 für alle drei Listenansichten mit layout_width als 0dp und Höhe als fill_parent zuweisen.
hoffe das hilft.
Können Sie Ihre aktuelle Lösung nicht in einer benutzerdefinierten Liste verwenden?
in der getView-Methode für jede Zeile pumpen Sie Ihre vorhandene Lösung auf (converview ofcourse prüfen) d. h. ScrollView mit drei Vertical LinearLayouts.
Weißt du, warum die 3-List-View-Lösung langsam war?
Wie viele verschiedene Größen gibt es in jeder Spalte? Ich denke, dass Sie für die effiziente Wiederverwendung von Ansichten einen Ansichtstyp für jede Bildgröße erstellen und dann sicherstellen sollten, dass Sie getItemViewType , um sicherzustellen, dass Sie den richtigen Ansichtstyp recyceln. Sonst werden Sie vom Recycling nicht viel profitieren. Sie möchten nur die Quelle für die Bildansicht zurücksetzen können.
Tags und Links android layout android-image