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

150

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

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

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

Римский
источник

Ответы:

394

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

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

Марк Эллисон
источник
3
Да, это именно то, что мне нужно. Я установил его 0в onPauseметод, и нет сбоев. Спасибо.
Роман
1
На ViewPager действительно очень мало документации. +1 за это.
Арнаб Чакраборти
1
если ваш пейджер занимает много времени для загрузки страницы, то вы можете использовать setOffscreenPageLimit (1), потому что по умолчанию просмотр пейджера загружает +1 и -1 страницу из текущей позиции
Ajay Pandya
Это не работает, я просто получаю сообщение о том, что фрагмент уже добавлен.
BlondeSwan
24

скользить вправо

viewPager.arrowScroll (View.FOCUS_RIGHT);

скользить влево

viewPager.arrowScroll (View.FOCUS_LEFT);

Аброр Эсоналиев
источник
коротко и чисто!
dakshbhatt21
1
Я почти верю, что это должен быть принятый ответ. Это гораздо более практично, чем установка текущего элемента.
Питер
18

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

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

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

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

RichardP
источник
1
плюс 1 за уведомлениеDataSetChanged ()
madhu527
@Richard Ты сохранишь моего дневного приятеля. 10000+ дляnotifyDataSetChanged()
Али
15

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

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);
Дэвид Фигероа
источник
1
Отлично! Я пытался использовать его без метода postDelay, и он не работал. Вы знаете, почему он работает с этим методом? Спасибо! :)
Георгий Коемджиев
Тот же вопрос ... почему товар меняется с такой задержкой, а не иначе?
Калян Рагху
@ GeorgiKoemdzhiev Потому что просмотр еще не закончен, когда вы звонитеviewPager.setCurrentItem
Зохаб Али
3

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

Первоначально у меня были проблемы с получением ссылки на 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);
    }

}
Suragch
источник