Как изменить страницу ViewPager?

Я использую ViewPager в своем приложении и определяю его в основном действии. Внутри метода onCreate я загружаю некоторое количество страниц из SharedPreferences, а затем передаю их в PagerAdapter:

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

Проблема в том, что если я изменю этот номер в настройках (или другом действии) на какой-либо другой, меньший, чем индекс страницы, который я просматривал ранее, мое приложение выйдет из строя, потому что этот индекс выходит за пределы, когда я возвращаюсь к действию с этим ViewPager. Это можно исправить, просто изменив активную страницу ViewPager. Есть ли способ сделать это?


person Roman    schedule 15.09.2011    source источник


Ответы (5)


Я не уверен, что полностью понимаю вопрос, но из названия вашего вопроса я предполагаю, что вы ищете pager.setCurrentItem( num ). Это позволяет вам программно переключаться на другую страницу в ViewPager.

Мне нужно увидеть трассировку стека из logcat, чтобы быть более конкретным, если это не проблема.

person Mark Allison    schedule 16.09.2011
comment
Да, это именно то, что мне нужно. Я установил его на 0 в методе onPause, и сбоев не было. Спасибо. - person Roman; 16.09.2011
comment
Документации по ViewPager действительно очень мало. +1 за это. - person Arnab Chakraborty; 20.09.2011
comment
если вашему пейджеру требуется много времени для загрузки страницы, вы можете использовать setOffscreenPageLimit(1), потому что по умолчанию просмотр пейджера загружает +1 и -1 страницу из текущей позиции - person Ajay Pandya; 09.04.2015
comment
Это не работает, я просто получаю сообщение о том, что фрагмент уже добавлен. - person BlondeSwan; 20.12.2019

сдвиньте вправо

viewPager.arrowScroll(View.FOCUS_RIGHT);

сдвиньте влево

viewPager.arrowScroll(View.FOCUS_LEFT);

person Abror Esonaliev    schedule 06.03.2017
comment
коротко и ясно! - person dakshbhatt21; 24.04.2017
comment
Я почти верю, что это должен быть принятый ответ. Это намного практичнее, чем установка текущего элемента. - person Peter; 04.05.2018

Не проверяя ваш код, я думаю, что вы описываете, что ваши страницы не синхронизированы и у вас устаревшие данные.

Вы говорите, что меняете количество страниц, а затем происходит сбой, потому что вы обращаетесь к старому набору страниц. Мне кажется, что вы не звоните pageAdapter.notifyDataSetChanged() после изменения ваших данных.

Когда ваш viewPager показывает страницу 3 из набора из 10 страниц, а вы переключаетесь на набор только из 5, затем позвоните notifyDataSetChanged(), вы обнаружите, что сейчас просматриваете страницу 3 нового набора. Если вы ранее просматривали страницу 8 старого набора, после установки нового набора и вызова notifyDataSetChanged() вы обнаружите, что теперь просматриваете последнюю страницу нового набора без сбоев.

Если вы просто измените текущую страницу, возможно, вы просто маскируете проблему.

person RichardP    schedule 26.01.2014
comment
плюс 1 для notifyDataSetChanged() - person madhu527; 05.01.2016
comment
@Richard Ты спас мой день, приятель. 10000+ за notifyDataSetChanged() - person Ali; 04.05.2020

для перехода на другую страницу попробуйте использовать этот код:

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);
person David Figueroa    schedule 15.09.2016
comment
Идеально! Я пытался использовать его без метода postDelay, и это не сработало. Вы знаете, почему это работает с этим методом? Спасибо! :) - person Georgi Koemdzhiev; 07.01.2017
comment
Тот же вопрос... почему элемент меняется с этой задержкой, а не иначе? - person Kalyan Raghu; 25.04.2018
comment
@GeorgiKoemdzhiev Потому что просмотр еще не закончен, когда вы звоните viewPager.setCurrentItem - person Zohab Ali; 12.09.2018

Дополнительный ответ

Первоначально у меня были проблемы с получением ссылки на ViewPager из других методов класса, потому что addOnTabSelectedListener создал анонимный внутренний класс, который, в свою очередь, требовал, чтобы переменная ViewPager была объявлена ​​final. Решение состояло в том, чтобы использовать переменную члена класса и не использовать анонимный внутренний класс.

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);
    }

}
person Suragch    schedule 05.12.2016