Як змінити сторінку 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 сторінку з поточної позиції
Аджай Пандія

Це не працює. Я просто отримую помилку, кажучи, що фрагмент вже додано.
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()ви побачите, що зараз переглядаєте останню сторінку нового набору без збоїв.

Якщо ви просто зміните свою поточну сторінку, можливо, ви просто замаскуєте проблему.


1
плюс 1 для notifyDataSetChanged ()
madhu527

@ Richard Ти врятуєш мені приятеля дня. 10000+ заnotifyDataSetChanged()
Алі

15

для переходу на іншу сторінку спробуйте скористатися цим кодом:

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);

1
Ідеально! Я намагався використовувати його без методу postDelay, і це не вийшло. Чи знаєте ви, чому це працює з цим методом? Дякую! :)
Георгій Кемджієв

Те саме питання ... чому елемент змінюється з цією затримкою, а не інакше?
Kalyan Raghu

@GeorgiKoemdzhiev Тому що перегляд ще не закінчений, коли ви телефонуєтеviewPager.setCurrentItem
Zohab Ali

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

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.