Wie ändere ich die ViewPager-Seite?

150

Ich verwende ViewPager in meiner App und definiere es in der Hauptaktivität. Innerhalb der onCreateMethode lade ich einige Seiten aus SharedPreferences und übergebe sie dann an PagerAdapter:

@Override
public int getCount() {
    return numberOfPages;
}

Das Problem ist, dass meine App abstürzt, wenn ich diese Nummer in den Einstellungen (oder einer anderen Aktivität) in einen anderen als den zuvor angezeigten Seitenindex ändern würde, da dieser Index außerhalb der Grenzen liegt, wenn ich mit diesem ViewPager zur Aktivität zurückkehre. Dies kann einfach durch Ändern der aktiven ViewPager-Seite behoben werden. Gibt es eine Möglichkeit, dies zu tun?

römisch
quelle

Antworten:

394

Ich bin mir nicht sicher, ob ich die Frage vollständig verstehe, aber aus dem Titel Ihrer Frage schätze ich, dass Sie danach suchen pager.setCurrentItem( num ). So können Sie programmgesteuert zu einer anderen Seite innerhalb der wechseln ViewPager.

Ich müsste einen Stack-Trace von logcat sehen, um genauer zu sein, wenn dies nicht das Problem ist.

Mark Allison
quelle
3
Ja, genau das brauche ich. Ich habe es auf 0in onPauseMethode gesetzt und es gibt keine Abstürze. Vielen Dank.
Roman
1
Es gibt in der Tat sehr wenig Dokumentation zu ViewPager. +1 dafür.
Arnab Chakraborty
1
Wenn Ihr Pager viel Zeit zum Laden der Seite benötigt, können Sie setOffscreenPageLimit (1) verwenden, da der Pager standardmäßig +1 und -1 Seite von der aktuellen Position lädt
Ajay Pandya
Dies funktioniert nicht Ich erhalte nur eine Fehlermeldung, dass das Fragment bereits hinzugefügt wurde.
BlondeSwan
24

nach rechts schieben

viewPager.arrowScroll (View.FOCUS_RIGHT);

nach links schieben

viewPager.arrowScroll (View.FOCUS_LEFT);

Abror Esonaliyev
quelle
kurz und sauber!
Dakshbhatt21
1
Ich glaube fast, dass dies die akzeptierte Antwort sein sollte. Es ist viel praktischer als das Einstellen des aktuellen Elements.
Peter
18

Ohne Ihren Code zu überprüfen, beschreiben Sie meiner Meinung nach, dass Ihre Seiten nicht synchron sind und Sie veraltete Daten haben.

Sie sagen, Sie ändern die Anzahl der Seiten und stürzen dann ab, weil Sie auf die alten Seiten zugreifen. Das klingt für mich so, als würden Sie pageAdapter.notifyDataSetChanged()nach dem Ändern Ihrer Daten nicht anrufen .

Wenn Sie viewPagerSeite 3 eines Satzes von 10 Seiten anzeigen und zu einem Satz mit nur 5 Seiten wechseln und dann anrufen notifyDataSetChanged(), sehen Sie, dass Sie jetzt Seite 3 des neuen Satzes anzeigen. Wenn Sie zuvor Seite 8 des alten Satzes angezeigt haben, werden Sie nach dem Einfügen des neuen Satzes und dem Aufrufen notifyDataSetChanged()feststellen, dass Sie jetzt die letzte Seite des neuen Satzes ohne Absturz anzeigen.

Wenn Sie einfach Ihre aktuelle Seite ändern, maskieren Sie möglicherweise nur das Problem.

RichardP
quelle
1
plus 1 für notifyDataSetChanged ()
madhu527
@ Richard Du rettest meinen Tag Kumpel. 10000+ fürnotifyDataSetChanged()
Ali
15

Versuchen Sie Folgendes, um zu einer anderen Seite zu wechseln:

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);
David Figueroa
quelle
1
Perfekt! Ich habe versucht, es ohne die postDelay-Methode zu verwenden, und es hat nicht funktioniert. Wissen Sie, warum es mit dieser Methode funktioniert? Vielen Dank! :)
Georgi Koemdzhiev
Gleiche Frage ... warum ändert sich der Artikel mit dieser Verzögerung und nicht anders?
Kalyan Raghu
@GeorgiKoemdzhiev Weil die Ansicht noch nicht fertig ist, wenn Sie anrufenviewPager.setCurrentItem
Zohab Ali
3

Ergänzende Antwort

Ich hatte ursprünglich Probleme, einen Verweis auf die ViewPagervon anderen Klassenmethoden zu erhalten, weil die addOnTabSelectedListenereine anonyme innere Klasse erstellt hat, für die wiederum die ViewPagerDeklaration der Variablen erforderlich war final. Die Lösung bestand darin, eine Klassenmitgliedsvariable und nicht die anonyme innere Klasse zu verwenden.

public class MainActivity extends AppCompatActivity {

    TabLayout tabLayout;
    ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        viewPager = (ViewPager) findViewById(R.id.pager);
        final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        // don't use an anonymous inner class here
        tabLayout.addOnTabSelectedListener(tabListener);

    }

    TabLayout.OnTabSelectedListener tabListener = new TabLayout.OnTabSelectedListener() {

        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    };

    // The view pager can now be accessed here, too.
    public void someMethod() {
        viewPager.setCurrentItem(0);
    }

}
Suragch
quelle