0

Ich versuche, eine Multidirektionale Paging-Anwendung zu erstellen, die auf einer Aktivität basiert, die einen Support ViewPager enthält und in denen Fragmente enthalten sind, die VerticalViewPagers enthalten. Beide ViewPager verwenden einen FragmentStatePagerAdapter und die Daten stammen von einem ContentProvider, der über CursorLoaders geladen wird. Die vertikalen Fragmente enthalten nur eine einfache TextView, die den Namen des horizontalen Fragments und die vertikale Fragmentposition hat.Leistungsproblem mit Multidirection ViewPager über ContentProvider und CursorLoader

Das Problem, das ich stolpere, ist, dass, wenn Sie horizontal bis zum Ende und wieder an den Anfang mehrere Seiten, die Benutzeroberfläche beginnt zu verzögern. Je mehr Sie dies tun, desto mehr Verzögerungen treten auf und schließlich können Sie von Anfang bis Ende blättern, ohne dass die Benutzeroberfläche jemals aktualisiert wird, da sie so lange dauert. Je mehr Sie horizontal paginieren, desto schlechter wird die UI-Verzögerung.

Ich habe den strikten Modus aktiviert, um zu sehen, ob auf dem UIhread zu viel Arbeit passiert, aber das ist es nicht. Ich habe auch versucht zu überprüfen, ob LeakCanary Speicherlecks finden kann, aber es hat noch nichts gefunden.

Ich habe gerade angefangen Tracing via Traceview zu machen, aber da ich gerade erst angefangen habe, muss ich das Problem noch genau lokalisieren (Traceview kenne ich noch nicht, aber ich arbeite daran).

So sieht der Android Monitor aus, wenn er horizontal und dann am Ende horizontal blättert. Sie werden feststellen, dass das Paging vertikal funktioniert. Android Monitor Output

Die hier sichtbaren Spitzen sind als VSync-Verzögerung farbcodiert. Ich habe auch bemerkt, dass, wenn Sie die App laufen lassen und es dort sitzen lassen, der Speicher langsam steigen wird, bis der Garbage Collector ausgeführt wird, was etwas Speicher freigibt und der langsame Anstieg wieder fortgesetzt wird.

Mein erster Gedanke ist, dass ich entweder die Loader falsch mache oder ein Problem mit Loadern und verschachtelten ViewPagers vorliegt.

Gibt es etwas grundsätzlich falsch mit dem, was ich hier versuche oder etwas falsch mit den Loadern usw.? Ich werde mich weiter damit beschäftigen, aber in der Zwischenzeit habe ich gehofft, ein paar Gedanken von anderen zu bekommen, was mein Problem sein könnte, oder einige Vorschläge, wie man das Problem genau identifizieren kann.

Ich habe eine sehr einfache Beispielanwendung erstellt, die bei https://github.com/hooked82/MultiDirectionalPaging

gefunden werden können Wenn Sie das Projekt nach unten ziehen und ausführen, auf dem ersten Start der App finden Sie die Schaltfläche „+“ in der Symbolleiste klicken müssen um die Datenbank zu füllen.

Es ist die VerticalViewPager von https://github.com/castorflex/VerticalViewPager

UPDATE 2016.08.01 Per Joes Antwort verwendet wird, ist die Ursache der Menge von Inflationen und Zerstörung von Ansichten, wenn Sie den Adapter des VerticalViewPager auslagern. Ich konnte den Parameter "swapCursor()" in meinem benutzerdefinierten FragmentStatePagerAdapter nicht implementieren, da der Adapter nicht mit neuen Daten aktualisiert wurde. Wenn ich swapCursor() implementieren würde, würde ich einen guten horizontalen Seitenwechsel erhalten, aber die Benutzeroberfläche meines Adapters würde nicht aktualisiert, wenn der Cursor über den geänderten Datensatz benachrichtigt wurde.

Ich habe den VerticalViewPager für eine benutzerdefinierte CursorRecyclerView vertauscht, um die gleiche Funktionalität zu erhalten, aber muss noch richtiges Schleudern des RecyclerView einrichten, um das des VerticalViewPagers nachzuahmen.

Danke für die Hilfe, Joe!

Antwort

1

Das Problem ist die Anzahl der Fragmenttransaktionen, die auf einem horizontalen Bildlauf auftreten.

1) In jedem Ansichtspager werden höchstens 3 Fragmente angezeigt. Für die Vertikale an Position v1 gibt es 3 Fragmente v0, v1 und v2. Wenn Sie von v1 nach v2 scrollen, wird das v0-Fragment zerstört und v3 wird in Erwartung des nächsten Scrolls erstellt.

Für jeden vertikalen Bildlauf können also maximal zwei Fragmentoperationen auftreten.

2) Jetzt existiert das Gleiche horizontal. Wenn an der Position h1, haben Sie Fragmente h0, h1, h2 erstellt. Jetzt, da auch die vertikalen Fragmente erstellt werden, haben Sie bis zu drei vertikale Fragmente für jede horizontale Fragmentierung. Jetzt werden die Dinge interessant. Angenommen, Sie sind ein v1 in jedem horizontalen Fragment passiert das folgende (schlimmsten Fall) Scrollen von h1 nach h2. Das erste h0 ist zerstört, aber auch das v0, v1, v2 frag gehört zu h0. Dann wird h3 zusammen mit at min v0/v1 erstellt. Wenn Sie jedoch zuvor zu v1 gescrollt haben, merkt es sich diese Position und erstellt auch v2.

Daher werden für jeden horizontalen Bildlauf mindestens 6 Fragmentoperationen und maximal 8 pro Bildlauf ausgeführt (dh bis zu 4x teurer). Wenn Sie in Sicht Inflation/Cleanup bekommen, kann dies sehr schnell multiplizieren, was zu Ihrem Leistungsproblem führt.

Sie sollten mindestens eine Recycler-Ansicht verwenden, um das vertikale Scrollen zu ermöglichen. Sie müssen wahrscheinlich die Scrolling-Ereignisse abfangen, um den Snap auf der Seite zu simulieren, die der View Pager bei Teil-Scrolls ausführt.

+0

Danke, Joe! Ich habe den VerticalViewPager mit einem RecyclerView ausgetauscht, und obwohl ich den Paging noch nicht vollständig implementiert habe, um den ViewPager nachzuahmen, ist dies der richtige Weg, den ich zur Lösung dieses Problems einschlagen werde. – hooked82