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));
Ответы
Ответ 1
Ответ KISS:
Просто используйте FragmentStatePagerAdapter вместо FragmentPagerAdapter.
Я получил ответ. Сначала я решил удалить этот вопрос, поскольку я делаю очень глупую ошибку, но этот ответ поможет кому-то, кто сталкивается с той же проблемой, что вместо FragmentPagerAdapter
используйте FragmentStatePagerAdapter
.
Как @BlackHatSamurai упоминается в комментарии:
Причина этого в том, что FragmentStatePagerAdapter
уничтожает как Фрагменты, которые не используются. FragmentPagerAdapter
нет.
Ответ 2
Использование FragmentStatePagerAdapter
не полностью устранило мою проблему, которая была аналогичной проблемой, когда onCreateView
не вызывался для дочерних фрагментов в представлении пейджера. Я на самом деле , размещая мой FragmentPagerAdapter
внутри другого Fragment
, поэтому FragmentManager
был общим для всех из них и, таким образом, сохранял экземпляры старых фрагментов. Исправление состояло в том, чтобы вместо этого передать экземпляр getChildFragmentManager
в конструктор FragmentPagerAdapter
в моем фрагменте хоста. Что-то вроде...
FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());
Метод getChildFragmentManager()
доступен через фрагмент, и это сработало для меня, потому что оно возвращает частный FragmentManager
для этого фрагмента специально для ситуаций, в которых требуется вложение фрагментов. Я надеюсь, что это поможет кому-то, у кого может быть такая же проблема, что и я!
- Имейте в виду, однако, чтобы использовать
getChildFragmentManager()
, ваша минимальная версия API должна быть как минимум 17 (4.2)
, поэтому это может привести к гаечным ключам в ваших передачах. Конечно, если вы используете фрагменты из библиотеки поддержки v4, вы должны быть в порядке.
Ответ 3
Существует два разных сценария:
1.) У вас одинаковый макет для каждого пейджера: В этом случае будет лучше, если вы расширите свой пользовательский адаптер PagerAdapter и вернуть один макет.
2.) У вас разный макет для каждого пейджера: В этом случае будет лучше, если вы расширите свой пользовательский адаптер FragmentStatePagerAdapter и возвращать различные фрагменты для каждого пейджера.
Ответ 4
Я сделал то, что @kanika и @Jraco11 опубликовали, но у меня все еще была проблема.
Итак, после многих изменений я нашел тот, который работал у меня, и был добавлен в мой FragmentPagerAdapter следующий код:
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
В соответствии с тем, что я прочитал, getItemPosition используется, чтобы уведомить ViewPager, обновлять или не обновлять элемент, а также избегать обновлений, если элементы в видимых позициях Не изменилось.
Ответ 5
Переопределить long getItemId (int position)
FragmentPagerAdapter
кэширует фрагменты, getItem
с помощью getItem
. Я столкнулся с тем же issue- даже после вызова notifyDataSetChanged()
getItem
не вызывался.
Это на самом деле функция, а не ошибка. Вам необходимо переопределить getItemId
чтобы вы могли правильно использовать свои фрагменты. Поскольку вы удаляете фрагменты, ваши позиции меняются. Как упоминалось в документах:
long getItemId (int position)
Возвращает уникальный идентификатор элемента в заданной позиции.
Реализация по умолчанию возвращает заданную позицию. Подклассы должны переопределять этот метод, если позиции элементов могут измениться.
Просто укажите уникальный идентификатор для каждого фрагмента, и все готово.
Использование FragementStatePagerAdapter
или возврат POSITION_NONE
в int getItemPosition (Object object)
неверно. Вы не получите никакого кэширования.
Ответ 6
Я обнаружил, что установка прослушивателя на макете табуляции остановила это от вызова, вероятно, потому что у них есть только место для одного прослушивателя на tabLayout.setOnTabSelectedListener
вместо массива слушателей.