FragmentPagerAdapter getItem не вызывается

Я не могу повторно использовать фрагмент в FragmentPagerAdapter.. Используя метод destroyItem (), он удаляет фрагмент, но по-прежнему не вызывает getItem () снова..Есть только 2-3 изображения, поэтому я использую FragmentPagerAdapter вместо FragmentStatePagerAdapter..

public class ExamplePagerAdapter extends FragmentPagerAdapter {

    ArrayList < String > urls;
    int size = 0;
    public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
        super(fm);
        urls = res;
        size = urls.size();
    }

    @Override
    public int getCount() {
        if (urls == null) {
            return 0;
        } else {
            return size;
        }

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = new FloorPlanFragment();
        Bundle b = new Bundle();
        b.putInt("p", position);
        b.putString("image", urls.get(position));
        Log.i("image", "" + urls.get(position));
        fragment.setArguments(b);
        return fragment;
    }
}

И В FragmentActivity,

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 

6 ответов


поцелуй ответ:

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

Я получил ответ.. Во-первых, я думал удалить этот вопрос, поскольку я делаю очень глупую ошибку, но этот ответ поможет кому-то, кто сталкивается с той же проблемой, что и FragmentPagerAdapter используйте FragmentStatePagerAdapter.

как @BlackHatSamurai упоминается в комментарии:

причина, по которой это работает, потому что FragmentStatePagerAdapter уничтожает как фрагменты, которые не используются. FragmentPagerAdapter нет.


С помощью FragmentStatePagerAdapter не полностью исправил мою проблему, которая была аналогичной проблемой, где onCreateView не вызывался для дочерних фрагментов в пейджере просмотра. Я на самом деле вложенности моя FragmentPagerAdapter в другой Fragment на FragmentManager был разделен на всех из них и, таким образом, сохранив экземпляры старых фрагментов. Исправление было кормить экземпляр getChildFragmentManager конструктора FragmentPagerAdapter в моем фрагменте хоста. Что-то как...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

на getChildFragmentManager() метод доступен через фрагмент, и это сработало для меня, потому что он возвращает private FragmentManager для этого фрагмента специально для ситуаций, в которых необходимы вложенные фрагменты. Надеюсь, это поможет кому-то, у кого может быть та же проблема, что и у меня!!

  • имейте в виду, однако использовать getChildFragmentManager() ваша минимальная версия API должна быть по крайней мере 17 (4.2), так что это может бросить гаечный ключ в шестеренки. Конечно, если вы используете фрагменты из библиотеки поддержки v4 вы должны быть в порядке.

существует два разных сценария : 1.) У вас одинаковый макет для каждого пейджера : В этом случае будет лучше, если вы расширите свой пользовательский адаптер по PagerAdapter и вернуть один макет.

2.) У вас есть другой макет для каждого пейджера : В этом случае будет лучше, если вы расширите свой пользовательский адаптер по FragmentStatePagerAdapter и возвращать разные fragmets для каждого пейджера.


Я сделал то, что @kanika и @ Jraco11 опубликовали, но у меня все еще была проблема.

Итак, после многих изменений я нашел тот, который работал для меня и был добавлен в мой FragmentPagerAdapter следующий код:

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

согласно тому, что я читал,getItemPosition используется для уведомления ViewPager следует ли обновлять элемент и избегать обновлений, если элементы в видимых позициях не изменились.


переопределить long getItemId (int position)

FragmentPagerAdapter кэширует фрагменты, которые он создает с помощью getItem. Я столкнулся с той же проблемой - даже после вызова notifyDataSetChanged() getItem не было.

это на самом деле фича, а не баг. Вам нужно переопределить getItemId чтобы вы могли правильно использовать свои фрагменты. Поскольку вы удаляете фрагменты, ваши позиции меняются. Как указано в документах:

long getItemId (int position)

возвращает уникальный идентификатор элемента в заданной позиции.

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

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

С помощью FragementStatePagerAdapter или возврата POSITION_NONE на int getItemPosition (Object object) - это неправильно. Вы не получите никакого кэширования.


Я обнаружил, что установка прослушивателя на вкладке-layout остановила этот вызов, вероятно, потому, что у них есть только место для одного прослушивателя на tabLayout.setOnTabSelectedListener вместо массива слушателей.