Android: неверное получение позиции в FragmentStatePagerAdapter

322
20 апреля 2017, 15:23

В вопросе TabLayout с отдельным классом на каждую вкладку без заголовков был предложен такой подход:

public class MyPageAdapter extends FragmentStatePagerAdapter {
    public MyPageAdapter(FragmentManager fm) {
        super(fm);
    }
    @Override
    public Fragment getItem(int pos) {
        Fragment fragment = null;
        switch (pos) {
            case 0:
                fragment = new TabOneFragment();
                break;
            case 1:
                fragment = new TabTwoFragment();
                break;
            case 2:
                fragment = new TabThreeFragment();
                break;
            case 3:
                fragment = new TabFourFragment();
                break;
        }
        return fragment;
    }
    @Override
    public int getCount() {
        return 4;
    }
}

У меня реализовано изменение надписи в ActionBar в зависимости от выбранной вкладки (а на самих вкладках вместо текста - иконки) следующим образом: в Activity определён метод

public void changeToolbarTitle(String title){
    toolbar.setTitle(title);
}

а во фрагментах в методе onCreateView вызывается

activity.changeToolbarTitle(getText(R.string.tab1title).toString());

Возникла проблема: надписи не соответствуют выбираемым вкладкам. В процессе отладки я установил, что при запуске приложения после выполнения блока case 0 из MyPageAdapter сразу (до отображения на экран) выполняется case 1, в результате чего активна первая по счёту вкладка, а надпись - от второй.

При переключени на соседнюю (вторую по счёту) вкладку выполняется блок case 2 (соответствует 3-ей вкладке) , а когда мы доходим до четвёртой по счёту, то судя по всему, pos принимает уже значение 4.

Можно ли на основе приведённой информации сказать, в чём проблема?

Answer 1

Без разницы от какого адаптера вы отнаследуетесь. Эффект будет они и тот же, адаптер грузит фрагменты, которые за экраном. Соответственно, кто последний загрузился того и тапки (как правило это точно не тот, который видит пользователь), за исключением только если вы выставите максимальное количество загруженных фрагментов == 1.

Если вы хотите чтобы данные были актуальные: Минимум - установите слушатель addOnPageChangeListener для ViewPager и в методе onPageSelected - вы будете знать точно какой экран видит юзер. А дальше все зависит только от вас, как вы по позиции узнаете какой тайтл нужен.

  • Или вы отрефакторите адаптер (уберете хардкод, добавите коллекцию с генерик объектом в котором будет инфа нужная для показа)
  • Или вы обратитесь через метод адаптера instantiateItem по позиции и получите ссылку на фрагмент, после чего вы можете вызвать нужный вам метод в этом фрагменте.
READ ALSO
Как передать содержимое уведомления в Activity при открытом приложении?

Как передать содержимое уведомления в Activity при открытом приложении?

Здравствуйте, я могу передать содержимое уведомления в активити при нажатии на само уведомление через Intent, вызвав onNewIntent

287
Почему не работает код удаления номера телефона контакта?

Почему не работает код удаления номера телефона контакта?

Необходимо реализовать удаление номера телефона из контактаМне посоветовали код, по словам автора кода у него всё работало

233
Как задается поведение интерфейсам?

Как задается поведение интерфейсам?

Почему при имплементировании некоторых интерфейсов они обладают уже неким поведением? Например MouseListener, ActionListener, KeyListener, большинство функциональных...

231
Как убрать поля вокруг текста у кнопки?

Как убрать поля вокруг текста у кнопки?

Хочу создать стиль для кнопки, чтобы в нем установить минимальные поля вокруг текстаКак должен выглядеть код такого стиля?

237