Wie bringt diese "StickyScrollView" -Implementierung die Ansicht an den Anfang der ScrollView?

8

In der Regel funktioniert die Funktionsweise von Sticky Headern so, dass eine Art scrollbarer Daten in Abschnitte mit jeweils eigener Kopfzeile unterteilt ist. Beim Abwärtsscrollen ersetzen die Kopfzeilen der nachfolgenden Abschnitte die Kopfzeile am oberen Rand von ScrollView . .

Was ich brauche, sind zusätzliche sticky-Header in jedem Abschnitt. Wenn zum Beispiel header1 an der Spitze bleibt, bleibt der Header seiner ersten Sektion - header1a - darunter stecken, aber wenn wir zur Sektion 1b kommen, ersetzt 1b's header 1a's , aber header1 bleibt am selben Ort hängen; und wenn wir schließlich zum Abschnitt 2 kommen, ersetzt header2 die aktuell festgefahrenen Header aus dem vorherigen Abschnitt - header1 und header1b .

Hier ist eine ScrollView -Implementierung, die sticky-Header eindimensional implementiert:
Ссылка

%Vor%

Was ich versuche, ist, es an meine Bedürfnisse anzupassen, aber ich habe versucht, in dieser Implementierung herumzustochern, um zu sehen, wie es funktioniert, und ich kann nicht herausfinden, wie es dazu kommt, dass die Ansicht hängen bleibt an die Spitze der ScrollView . Hat jemand eine Idee, wie das funktioniert?

Bearbeiten:

Hier ist das Layout, das ich auch auf dieses Konzept anwenden möchte:
* Beachten Sie, dass die Headers (Header 1 und 2) benutzerdefinierte ViewGroups sind, die Sub-Headers enthalten (Header 1a, 1b, 2a); Dies sind auch benutzerdefinierte ViewGroups , die benutzerdefinierte Ansichten enthalten, die Items sind.

    
shoe 11.12.2016, 04:02
quelle

3 Antworten

5

Die StickyScrollView , die Sie verwenden, speichert nur ein Tag, ob es sticky sein soll oder nicht und wenn nicht, welches Kind von scrollview ist es header, und dementsprechend behält es es als eine erste untergeordnete Ansicht bei. Wenn Sie dieses StickyScrollView nur verwenden möchten, müssen Sie es ändern und ein weiteres Tag als Unterkopf pflegen. Ich schlage vor, eher ScrollView zu verwenden, Sie können diese ListView verwenden. Es ist sehr einfach zu implementieren und es funktioniert.

    
Charu 14.12.2016 05:06
quelle
4

Sie können header-decor für Ihre Anforderung verwenden. Intern verwendet es RecyclerView , also ist es ratsam, es zu verwenden. Überprüfen Sie den Abschnitt Double Header in der folgenden Abbildung.

Hoffe, das wird dir helfen.

    
Pravin Divraniya 13.12.2016 14:46
quelle
4

Das ist keine Raketenwissenschaft. Es gibt zwei Schlüsselelemente, um dies zu verstehen.

Erstens ist in der Methode doTheStickyThing . Dies ergibt, was wohin geht.

Der erste Schritt besteht darin herauszufinden, welcher Header zu halten ist. Wenn Sie nach unten blättern, haben Sie Ansichten über und unter dem oberen Rand der Bildlaufansicht. Sie möchten die unterste Kopfzeile beibehalten, die sich immer noch über dem oberen Rand der Bildlaufansicht befindet. Du siehst also viele Ausdrücke wie diese:

%Vor%

Dieser resultierende Wert ist nur der Versatz des oberen Teils der Ansicht vom oberen Rand der Bildlaufansicht. Wenn sich die Kopfzeile über dem oberen Rand der Bildlaufansicht befindet, ist der Wert negativ. Es stellt sich also heraus, dass die Kopfzeile mit dem größten Versatzwert, der immer noch kleiner oder gleich Null ist, verwendet werden soll. Die Gewinneransicht wird viewThatShouldStick zugewiesen.

Nun, da Sie einen steckenden Header haben, wollen Sie wissen, welche der folgenden Header beim Scrollen den einen aus dem Weg schieben könnte. Das wird approachingView

zugewiesen

Wenn die sich nähernde Ansicht die Kopfzeile aus dem Weg schiebt, müssen Sie den Kopf der Kopfzeile versetzen. Dieser Wert wird stickyViewTopOffset

zugewiesen

Der zweite Schlüsselteil zeichnet den Header. Das ist in dispatchDraw gemacht.

Hier ist der Trick, um die Ansicht "hängen zu lassen": Die normale Rendering-Logik möchte diesen Header an einer bestimmten Stelle basierend auf seinen aktuellen Grenzen setzen. Wir können einfach die Zeichenfläche (Translate) unterhalb dieser Kopfzeile verschieben, so dass sie am oberen Rand der Bildlaufleiste statt an der Stelle gezeichnet wird, an der sie normalerweise gezeichnet würde. Dann sagen wir der Ansicht, dass sie sich selbst zeichnen soll. Dies geschieht, nachdem alle Listenelementansichten bereits gezeichnet wurden, sodass die Kopfzeile scheinbar über den Listenelementen liegt.

Wenn wir die Leinwand verschieben, müssen wir auch den Fall berücksichtigen, in dem ein weiterer herannahender Header diesen aus dem Weg räumt. Das Clipping behandelt einige Eckfälle, wie es aussehen sollte, wenn Padings beteiligt sind.

Ich habe angefangen, den Code zu modifizieren, um das zu tun, was Sie wollten, aber die Dinge wurden schnell kompliziert.

Anstatt zwei Header zu verfolgen, müssen Sie drei Header verfolgen: Header, Subheader und herannahende Header. Jetzt müssen Sie den oberen Offset des Subheaders zusammen mit dem oberen Offset des Headers behandeln. Und dann haben Sie zwei Szenarien: Erstens ist der sich nähernde Header ein Hauptheader. Dies wird beide Top-Offsets verändern. Wenn der sich nähernde Header jedoch ein Header sub ist, wird nur der obere Offset des fixierten Subheaders beeinflusst und der Hauptheaderversatz bleibt gleich.

Ich kann das bekommen, aber ich habe gerade keine Zeit. Ich beende den Code und poste ihn, wenn ich die Zeit finde.

    
kris larson 14.12.2016 19:30
quelle

Tags und Links