Wie legen Sie den Spaltenabstand mit einem RecyclerView mithilfe eines GridLayoutManager fest? Das Einstellen des Randes / der Polsterung in meinem Layout hat keine Auswirkung.
250
Wie legen Sie den Spaltenabstand mit einem RecyclerView mithilfe eines GridLayoutManager fest? Das Einstellen des Randes / der Polsterung in meinem Layout hat keine Auswirkung.
GridLayoutManager
und ÜberschreibungengenerateDefaultLayoutParams()
und Verwandte?Antworten:
RecyclerViews unterstützen das Konzept von ItemDecoration : spezielle Offsets und Zeichnen um jedes Element. Wie in dieser Antwort zu sehen , können Sie verwenden
Dann fügen Sie es über hinzu
quelle
RecyclerView
(und VerwendungclipToPadding="false"
) verwenden, können Sie die Dinge leicht umstrukturieren. Wenn Sie dies jedoch nicht tun, verschieben Sie den if-Check nur auf das letzte Mal (da Sie immer noch die untere Polsterung des letzten Elements wünschen).GridLayoutManager
. Die Antwort funktioniert nicht bei mehrspaltigen /Der folgende Code funktioniert gut und jede Spalte hat die gleiche Breite:
Verwendung
1. keine Kante
2. mit Kante
quelle
Das Folgende ist die schrittweise einfache Lösung, wenn Sie den gleichen Abstand um Artikel und gleiche Artikelgrößen wünschen.
ItemOffsetDecoration
Implementierung
In Ihrem Quellcode sollte das Hinzufügen
ItemOffsetDecoration
zu IhremRecyclerView.
Artikelversatzwert die halbe Größe des tatsächlichen Werts haben, den Sie als Leerzeichen zwischen Elementen hinzufügen möchten.Legen Sie außerdem den Elementversatzwert als Auffüllung für seine fest
RecyclerView
und geben Sie ihn anandroid:clipToPadding=false
.quelle
Versuche dies. Es wird sich um gleichmäßige Abstände kümmern. Funktioniert sowohl mit List, Grid als auch StaggeredGrid.
Bearbeitet
Der aktualisierte Code sollte die meisten Eckfälle mit Bereichen, Ausrichtung usw. behandeln. Beachten Sie, dass bei Verwendung von setSpanSizeLookup () mit GridLayoutManager aus Leistungsgründen das Festlegen von setSpanIndexCacheEnabled () empfohlen wird.
Beachten Sie, dass es bei StaggeredGrid anscheinend einen Fehler gibt, bei dem der Index der Kinder verrückt und schwer zu verfolgen ist, sodass der folgende Code möglicherweise nicht sehr gut mit StaggeredGridLayoutManager funktioniert.
Ich hoffe es hilft.
quelle
Der folgende Code behandelt StaggeredGridLayoutManager, GridLayoutManager und LinearLayoutManager.
Dann benutze es
quelle
SpaceItemDecoration
fügt die Auffüllung tatsächlich dem übergeordneten Element hinzu (die Recycler-Ansicht).halfSpace
Polsterung erschien (auf der rechten Seite), als ich die Polsterung nicht auf das übergeordnete Element in XML gesetzt hatteHier ist eine Lösung, die kein "spanCount" (Anzahl der Spalten) erfordert. Ich verwende sie, weil ich GridAutofitLayoutManager verwende (berechnet die Anzahl der Spalten entsprechend der erforderlichen Zellengröße).
(Beachten Sie, dass dies nur mit GridLayoutManager funktioniert. )
Hier ist der GridAutofitLayoutManager, an dem sich jeder interessiert:
Schließlich:
quelle
layoutManager.getPosition(view)
: Überprüfen Sie anschließend, ob die Position Null ist, die Ihre Überschrift sein wird. Auf diese Weise können Sie auch an jeder gewünschten Position eine weitere Überschrift hinzufügen :)Es gibt nur eine einfache Lösung, an die Sie sich erinnern und die Sie bei Bedarf implementieren können. Keine Bugs, keine verrückten Berechnungen. Fügen Sie dem Karten- / Elementlayout einen Rand hinzu und fügen Sie dem RecyclerView dieselbe Größe wie dem Auffüllen hinzu:
item_layout.xml
activity_layout.xml
AKTUALISIEREN:
quelle
Wenn Sie die Größe Ihres Artikels auf allen Geräten FESTLEGEN möchten
RecyclerView
. Sie können dies tunrecyclerview_item.xml
dimension.xml
Aktivität
quelle
Die ausgewählte Antwort ist nahezu perfekt, aber je nach Platz kann die Breite der Elemente nicht gleich sein. (In meinem Fall war es kritisch). Also habe ich diesen Code erhalten, der den Platz ein wenig vergrößert, sodass alle Elemente die gleiche Breite haben.
quelle
columnCount == 1 -> { outRect.left = space outRect.right = space }
Der von @edwardaa bereitgestellte Code wurde kopiert und ich mache es perfekt, um RTL zu unterstützen:
quelle
In den obigen Antworten wurden Möglichkeiten zum Festlegen der Margin-Behandlung für GridLayoutManager und LinearLayoutManager erläutert.
Für StaggeredGridLayoutManager lautet die Antwort von Pirdad Sakhizada jedoch: "Mit StaggeredGridLayoutManager funktioniert es möglicherweise nicht sehr gut." Es sollte das Problem mit IndexOfSpan sein.
Sie können es auf diese Weise erhalten:
quelle
Ein bisschen anders als die Antwort von edwardaa besteht der Unterschied darin, wie die Spalte bestimmt wird, da in Fällen wie Elementen mit unterschiedlichen Höhen die Spalte nicht einfach durch% bestimmt werden kann
spanCount
quelle
quelle
Hier ist meine Modifikation
SpacesItemDecoration
, die numOfColums und Leerzeichen oben, unten, links und rechts gleichermaßen einnehmen kann .und verwenden Sie den folgenden Code für Ihre Logik.
quelle
Es gibt eine sehr einfache und dennoch flexible Lösung für dieses Problem, bei der nur XML verwendet wird, das auf jedem LayoutManager funktioniert.
Angenommen, Sie möchten einen gleichen Abstand von X (z. B. 8 dp).
Wickeln Sie Ihr CardView-Element in ein anderes Layout
Geben Sie dem äußeren Layout eine Polsterung von X / 2 (4dp).
Machen Sie den äußeren Layouthintergrund transparent
...
...
und das ist es. Sie haben einen perfekten Abstand von X (8dp).
quelle
Für diejenigen, die Probleme mit staggeredLayoutManager haben (wie https://imgur.com/XVutH5u )
Methoden von recyclerView:
Geben Sie manchmal -1 als Index zurück, damit beim Festlegen von itemDecor Probleme auftreten können. Meine Lösung besteht darin, die veraltete ItemDecoration-Methode zu überschreiben:
anstelle des Neulings:
so was:
Scheint bisher für mich zu arbeiten :)
quelle
Die Antworten auf diese Frage scheinen komplexer zu sein, als sie sein sollten. Hier ist meine Meinung dazu.
Angenommen, Sie möchten einen Abstand von 1 dp zwischen Rasterelementen. Mach Folgendes:
quelle
Dies funktioniert auch
RecyclerView
mit dem Header.quelle
Die Antwort von yqritc hat bei mir perfekt funktioniert. Ich habe jedoch Kotlin verwendet, daher ist hier das Äquivalent dazu.
alles andere ist das gleiche.
quelle
Seien Sie vorsichtig, für StaggeredGridLayoutManager- Benutzer. Viele Antworten hier, einschließlich der am häufigsten bewerteten, berechnen die Elementspalte mit dem folgenden Code:
Dies setzt voraus, dass sich die Elemente 1st / 3rd / 5th / .. immer auf der linken Seite und die Elemente 2nd / 4th / 6th / .. immer auf der rechten Seite befinden. Ist diese Annahme immer wahr? Nein.
Angenommen, Ihr 1. Artikel ist 100 dp hoch und der 2. nur 50 dp. Ratet mal, wo sich Ihr 3. Artikel befindet, links oder rechts?
quelle
So habe ich es für meinen RecyclerView mit GridLayoutManager und HeaderView gemacht .
Im folgenden Code habe ich einen 4-dp-Abstand zwischen jedem Element festgelegt (2 dp um jedes einzelne Element und 2 dp-Auffüllung um die gesamte Recycling-Ansicht).
layout.xml
Fragment / Aktivität
SpaceItemDecoration.java
Utils.java
quelle
Damit die Lösung von https://stackoverflow.com/a/29905000/1649371 (oben) funktioniert, musste ich die folgenden Methoden (und alle nachfolgenden Aufrufe) ändern.
quelle
Dieser Link hat für mich in allen Situationen funktioniert, in denen Sie dies versuchen können.
quelle
Wenn Sie einen Kippschalter haben, der zwischen Liste und Raster umschaltet, vergessen Sie nicht, den Anruf zu tätigen,
recyclerView.removeItemDecoration()
bevor Sie eine neue Objektdekoration einstellen. Wenn nicht, wären die neuen Berechnungen für den Abstand falsch.Etwas wie das.
quelle
Wenn Sie Header mit GridLayoutManager verwenden, verwenden Sie diesen in Kotlin geschriebenen Code für den Abstand zwischen den Gittern:
Und
ItemDecoration
weiterrecyclerview
alsquelle
Bei Verwendung von CardView für Kinder können Probleme mit Leerzeichen zwischen Elementen behoben werden, indem app: cardUseCompatPadding auf true gesetzt wird.
Für größere Ränder vergrößern Sie die Elementhöhe. CardElevation ist optional (Standardwert verwenden).
quelle
danke edwardaas antwort https://stackoverflow.com/a/30701422/2227031
Ein weiterer zu beachtender Punkt ist:
Wenn der Gesamtabstand und die Gesamtgröße des Elements nicht der Bildschirmbreite entsprechen, müssen Sie auch die Breite des Elements anpassen, z. B. für die Methode adapter onBindViewHolder
quelle
Eine Kotlin-Version, die ich basierend auf der großartigen Antwort von edwardaa gemacht habe
quelle