Android ViewPager setCurrentItem funktioniert nach onResume nicht

Lesezeit: 6 Minuten

Android ViewPager setCurrentItem funktioniert nach onResume nicht
Maciej Boguta

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.

  • 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

Android ViewPager setCurrentItem funktioniert nach onResume nicht
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

1642335068 85 Android ViewPager setCurrentItem funktioniert nach onResume nicht
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

1642335068 369 Android ViewPager setCurrentItem funktioniert nach onResume nicht
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()

1642335068 86 Android ViewPager setCurrentItem funktioniert nach onResume nicht
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

1642335068 914 Android ViewPager setCurrentItem funktioniert nach onResume nicht
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

Android ViewPager setCurrentItem funktioniert nach onResume nicht
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

.

505240cookie-checkAndroid ViewPager setCurrentItem funktioniert nach onResume nicht

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy