it-swarm.com.ru

FragmentPagerAdapter getItem не запускается

В настоящее время, с FragmentActivity, я переключаюсь между 2 типами фрагментов, используя следующий код.

private void toggle() {
    Fragment oldFragment = getSupportFragmentManager().findFragmentById(R.id.content);
    Fragment fragment = null;
    if (oldFragment instanceof ColorFragment) {
        fragment = new ViewPagerFragment();
    } else {
        fragment = new ColorFragment(Android.R.color.black);
    }

    getSupportFragmentManager().beginTransaction().replace(R.id.content, fragment).commitAllowingStateLoss();
}

2 фрагмента переключаются.

  • ColorFragment - простой фрагмент, который заполняет его фон сплошным черным цветом.
  • ViewPagerFragment - Фрагмент содержит ViewPager. Пользователь может провести между фрагментом фиолетового цвета и фрагментом синего цвета.

Код, который отвечает за считывание фрагментов фиолетового и синего цветов, приведен ниже.

private static class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

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

    @Override
    public Fragment getItem(int position) {
        switch (position) {
        case 0:
            return new ColorFragment(Android.R.color.holo_purple);
        default:
            return new ColorFragment(Android.R.color.holo_blue_bright);
        }
    }      
} 

Тем не менее, я сталкиваюсь со странным поведением во время переключения.

  1. Был показан фрагмент черного цвета.
  2. Переключение.
  3. Просмотр пейджера, который может проводить пальцем между фиолетовым и синим фрагментами.
  4. Переключение.
  5. Был показан фрагмент черного цвета.
  6. Переключение.
  7. Ничего не показано, так как метод getItem MyFragmentPagerAdapter не запускается.

Я думаю, что моя ситуация похожа на FragmentPagerAdapter getItem не вызывается

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

Любой способ обойти эту проблему?

Я включил полный работающий исходный код, чтобы продемонстрировать эту проблему: https://www.dropbox.com/s/jok9tz5ktvfcteo/viewpagerbug.Zip

35
Cheok Yan Cheng

Любой способ обойти эту проблему?

Я скачал ваш код, и проблема возникает из-за того, что вы не обрабатываете эти Fragments правильно. Наиболее точно вы используете вложенный Fragments в ViewPager на основе Fragment и для этого ViewPager вы создаете адаптер следующим образом:

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getFragmentManager());

Вместо этого вы должны использовать getChildFragmentManager() для связывания вложенных фрагментов:

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getChildFragmentManager());

Кроме того, вы не должны передавать данные через конструктор Fragment, так как эти данные не выдержат изменения конфигурации и начнут появляться плохие вещи. Вместо этого используйте Bundle.

107
Luksprog

Глобальное рабочее проверенное решение.

getSupportFragmentManager() несколько раз сохраняет нулевую ссылку, а пейджер View не создает новый экземпляр фрагмента. Так как он находит ссылку на тот же фрагмент. Таким образом, чтобы преодолеть это использование getChildFragmentManager() решает проблему простым способом.

Не  

new PagerAdapter(getSupportFragmentManager(), fragments);

Делать

new PagerAdapter(getChildFragmentManager() , fragments);

12
Vinayak

В моем случае я правильно звонил

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getChildFragmentManager());

но затем во вложенном фрагменте я пытался заменить фрагмент контейнера другим, используя:

getFragmentManager()

Вам нужно перейти на мероприятие и позвонить

getActivity().getSupportFragmentManager();
1
kingston

В моих случаях это работало после добавления этого в мой FragmentPagerAdapter :

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

и я также использовал getChildFragmentManager () , как сказал Luksprog

0
Jorge Casariego

Простое использование FragmentStatePagerAdapter вместо FragmentPagerAdapter

или же

вы можете использовать new MyFragmentPagerAdapter(this.getChildFragmentManager())

Надеюсь, это поможет вам :)

0
Neo