Ich habe dieses seltsame Problem, ViewPager
‘S setCurrentItem(position, false)
funktioniert einwandfrei, dann wechsle ich zu einer anderen Aktivität, und nachdem ich zurück zur ersten Aktivität bin, die ViewPager
landet immer beim ersten Artikel. Obwohl ich hinzugefügt habe setCurrentItem
zu onResume
Methode ignoriert es immer noch. Es löst nicht einmal eine Ausnahme aus, wenn ich versuche, das Element auf den Index außerhalb der Grenzen zu setzen. Später, wenn ich diese Methode aufrufe, funktioniert es wie erwartet, wenn auf die Schaltfläche “Weiter” getippt wird. Habe meinen Code 10 mal auf eventuelle Anrufe überprüft setCurrentItem(0)
oder so, aber es ist einfach überhaupt nicht da.
Android ViewPager setCurrentItem funktioniert nach onResume nicht
Maciej Boguta
stefs
Ich kann nicht wirklich beantworten, WARUM genau das passiert, aber wenn Sie den Aufruf von setCurrentItem um einige Millisekunden verzögern, sollte es funktionieren. Meine Vermutung ist, dass, weil während onResume
Es gab noch keinen Rendering-Pass, und der ViewPager braucht einen oder so etwas.
private ViewPager viewPager;
@Override
public void onResume() {
final int pos = 3;
viewPager.postDelayed(new Runnable() {
@Override
public void run() {
viewPager.setCurrentItem(pos);
}
}, 100);
}
UPDATE: Geschichtenzeit
also hatte ich heute das problem, dass der viewpager meine setCurrentItem aktion ignorierte, und ich habe stackoverflow nach einer lösung gesucht. ich habe jemanden mit dem gleichen Problem und einer Lösung gefunden; Ich habe den Fix implementiert und es hat nicht funktioniert. wow! zurück zum Stapelüberlauf, um diesen Faux-Fix-Anbieter abzulehnen, und …
ich war es. Ich habe mein eigenes fehlerhaftes Non-Fix implementiert, auf das ich beim ersten Mal gestoßen bin, als ich über das Problem gestolpert bin (und das später vergessen wurde). Ich muss mich jetzt selbst dafür abwerten, dass ich schlechte Informationen bereitgestellt habe.
Der Grund, warum mein anfängliches “Fix” funktionierte, war nicht wegen eines “Rendering-Passes”. Das Problem war, dass der Inhalt des Pagers von einem Spinner gesteuert wurde. sowohl der Spinner- als auch der Pager-Status wurden onResume wiederhergestellt, und aus diesem Grund wurde der Spinner-onItemSelected-Listener während des nächsten Ereignisweitergabezyklus aufgerufen, der den Viewpager erneut auffüllte – diesmal mit einem anderen Standardwert.
Das Entfernen und Zurücksetzen des Listeners während der Wiederherstellung des ursprünglichen Zustands behebt das Problem.
Der obige Fix funktionierte irgendwie beim ersten Mal, weil er die aktuelle Position des Pagers festlegte nach das onItemSelected-Ereignis ausgelöst. später funktionierte es aus irgendeinem Grund nicht mehr (wahrscheinlich wurde die App zu langsam – in meiner Implementierung habe ich nicht 100 ms, sondern 10 ms verwendet). ich habe dann postDelayed in einem Bereinigungszyklus entfernt, weil es das bereits fehlerhafte Verhalten nicht geändert hat.
Aktualisierung 2: Ich kann meinen eigenen Beitrag nicht downvoten. Ich nehme an, ehrenhafter Seppuku ist die einzige verbleibende Option.
-
Was meinen Sie damit, dass der Inhalt des Pagers von einem Spinner gesteuert wurde? Sprechen Sie über die zugrunde liegende Implementierung des ViewPagers oder sagen Sie, dass der Inhalt jeder Seite im ViewPager einen Spinner enthielt? Und ich habe immer noch diesen Fehler, auch wenn ich als erstes in onResume() super.onResume() aufrufe. Dadurch sollten die Ansichtszustände wiederhergestellt werden, und ich sollte mich nicht mit dem befassen müssen, was Sie oben beschrieben haben
– Andreas Orobator
29. Juli 14 um 0:38 Uhr
-
nein, ich meine: je nach ausgewähltem Item im Spinner wurde der Viewpager (also der Adapter) mit unterschiedlichen Items bestückt. in onResume wurden sowohl der Spinner als auch der Pager neu initialisiert und der onItemSelected-Callback des Spinners zum Aktualisieren des Viewpagers “überschrieb” die korrekt eingestellte Viewpager-Position. es war meine eigene Schuld, der Viewpager funktionierte korrekt.
– Stefs
29. Juli 14 um 11:02 Uhr
-
wie gesagt, bei mir war das problem etwas ganz anderes, nämlich das anrufen
setCurrentItem()
zweimal. Ich denke, das gleiche gilt auch in Ihrem Fall.– Stefs
11. Februar 15 um 12:07 Uhr
-
@ user3560827 Ich bin sicher, dass Sie entweder setCurrentItem danach erneut aufrufen oder einen neuen Adapter zuweisen, dank einiger Lebenszyklus-Spielereien oder vielleicht nach einer asynchronen Operation. Verlassen Sie sich NICHT auf postDelayed, es ist ein Hack und praktisch technische Schuld. dein problem liegt woanders!
– Stefs
17. August 16 um 6:33 Uhr
-
Wow, diese Geschichte verdient eine Netflix-Adaption
– Ilja E
26. September 21 um 6:41 Uhr
Ich hatte ein ähnliches Problem im OnCreate meiner Aktivität. Der Adapter wurde mit der richtigen Anzahl eingerichtet und ich habe setCurrentItem angewendet, nachdem ich den Adapter auf den ViewPager eingestellt hatte, aber er würde den Index außerhalb der Grenzen zurückgeben. Ich denke, der ViewPager hatte nicht alle meine Fragmente geladen, als ich das aktuelle Element eingestellt habe. Durch das Posten eines Runnable auf dem ViewPager konnte ich dies umgehen. Hier ist ein Beispiel mit ein wenig Kontext.
// Locate the viewpager in activity_main.xml
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
// Set the ViewPagerAdapter into ViewPager
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
viewPager.setOffscreenPageLimit(2);
viewPager.post(new Runnable() {
@Override
public void run() {
viewPager.setCurrentItem(ViewPagerAdapter.CENTER_PAGE);
}
});
-
@TylerPfaff das hat auch bei mir funktioniert. Anscheinend ignoriert der ViewPager “Early-into-the-Activity”-Anweisungen, weil er noch nicht weiß, was zu rendern ist
– Chisko
6. Juli 17 um 17:30 Uhr
-
@TylerPfaff Ich glaube, es hat etwas damit zu tun, wann der ViewPager und seine Kinder gemessen werden. Es scheint setCurrentItem zu ignorieren, bis das abgeschlossen ist. Das auf dem ViewPager gepostete Runnable wird nach dieser Maßnahme garantiert ausgeführt.
– Martin Preis
24. August 17 um 9:24 Uhr
Android-Entwickler
Ich habe eine sehr einfache Problemumgehung dafür gefunden:
if (mViewPager.getAdapter() != null)
mViewPager.setAdapter(null);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setCurrentItem(desiredPos);
Und wenn das nicht funktioniert, können Sie es in einen Handler stecken, aber es ist keine zeitliche Verzögerung erforderlich:
new Handler().post(new Runnable() {
@Override
public void run() {
mViewPager.setCurrentItem(desiredPos);
}
});
-
Danke, der zweite Ansatz hat mein Problem behoben.
– Faul
27. August 15 um 15:04 Uhr
petrumo
Ich hatte einen ähnlichen Fehler im Code, das Problem war, dass ich die Position eingestellt habe, bevor ich die Daten geändert habe.
Die Lösung bestand einfach darin, die Position nachträglich einzustellen und die geänderten Daten mitzuteilen
notifyDataSetChanged()
setCurrentItem()
sanya5791
ViewTreeObserver kann verwendet werden, um eine statische Verzögerung zu vermeiden.
Kotlin:
Fühlen Sie sich frei, die Kotlin-Erweiterung als prägnante Option zu verwenden.
view_pager.doOnPreDraw {
view_pager.currentItem = 1
}
Bitte stellen Sie sicher, dass Sie eine Gradle-Abhängigkeit haben: Implementierung ‘androidx.core:core-ktx:1.3.2’ oder höher
Java
OneShotPreDrawListener.add(view_pager, () -> view_pager.currentItem = 1);
-
tolle Antwort – einzige Lösung, die in viewpager2 funktioniert hat!
– Henrique Vasconcellos
21. September 21 um 21:30 Uhr
Abdulaziz Noor
Ich habe das gleiche Problem und ich bearbeite
@Override
public int getCount() { return NUM_PAGES; }
ich setze NUM_PAGES
sein Fehler zu 1 nur.
-
tolle Antwort – einzige Lösung, die in viewpager2 funktioniert hat!
– Henrique Vasconcellos
21. September 21 um 21:30 Uhr
Andrei Tschernyschew
ein Typ hat hier im Forum geschrieben. https://code.i-harness.com/en/q/126bff9 hat bei mir funktioniert
if (mViewPager.getAdapter() != null)
mViewPager.setAdapter(null);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setCurrentItem(desiredPos);
-
Du bist der beste. Das hat endlich funktioniert. Ich habe Daten von einer Volley-JSON-Anfrage erhalten. Die Ansichten waren zunächst leer. Ich habe viele Lösungen ausprobiert, aber keine davon hat funktioniert. aber du hast wie von Zauberhand gearbeitet. Danke.
– MindRoasterMir
13. April 19 um 11:11 Uhr
.
jeder Ausschnitt wäre besser
– imthegiga
11. Oktober 13 um 11:20 Uhr
Ich hatte ein ähnliches Problem, ich habe gerade den Code verschoben, der das aktuelle Element festlegt, unter dem Einstellen des Adapters. Ich meine, stellen Sie sicher, dass Sie zuerst den Adapter einstellen und dann die Position einstellen.
– hazimdikenli
7. April 16 um 19:03 Uhr