Существует другое решение, которое не требует изменения исходного кода ViewPager
и FragmentStatePagerAdapter
, и оно работает с базовым классом FragmentPagerAdapter
, используемым автором.
Я хотел бы начатьотвечая на вопрос автора о том, какой ID он должен использовать;это идентификатор контейнера, т.е. идентификатор самого пейджер просмотра.Однако, как вы, вероятно, заметили, использование этого идентификатора в вашем коде ничего не даст.Я объясню, почему:
Прежде всего, чтобы ViewPager
снова заполнил страницы, вам нужно вызвать notifyDataSetChanged()
, который находится в базовом классе вашего адаптера.
Во-вторых, ViewPager
использует абстрактный метод getItemPosition()
, чтобы проверить, какие страницы должны быть уничтожены, а какие должны быть сохранены.Реализация этой функции по умолчанию всегда возвращает POSITION_UNCHANGED
, в результате чего ViewPager
сохраняет все текущие страницы и, следовательно, не присоединяет вашу новую страницу.Таким образом, чтобы замена фрагмента работала, getItemPosition()
должен быть переопределен в вашем адаптере и должен возвращать POSITION_NONE
при вызове со старым, чтобы быть скрытым, фрагмент в качестве аргумента.
Это также означает, что ваш адаптервсегда нужно знать, какой фрагмент должен отображаться в позиции 0, FirstPageFragment
или NextFragment
.Один из способов сделать это - предоставить слушателя при создании FirstPageFragment
, который будет вызываться, когда пришло время переключать фрагменты.Я думаю, что это хорошо, если ваш адаптер фрагментов обрабатывает все переключатели фрагментов и вызывает ViewPager
и FragmentManager
.
В-третьих, FragmentPagerAdapter
кэширует используемые фрагменты по имени, которое является производнымс позиции, поэтому, если в позиции 0 был фрагмент, он не будет заменен, даже если класс новый.Есть два решения, но самое простое - использовать функцию remove()
FragmentTransaction
, которая также удалит его тег.
Это было много текста, вот код, который должен работать в вашемcase:
public class MyAdapter extends FragmentPagerAdapter
{
static final int NUM_ITEMS = 2;
private final FragmentManager mFragmentManager;
private Fragment mFragmentAtPos0;
public MyAdapter(FragmentManager fm)
{
super(fm);
mFragmentManager = fm;
}
@Override
public Fragment getItem(int position)
{
if (position == 0)
{
if (mFragmentAtPos0 == null)
{
mFragmentAtPos0 = FirstPageFragment.newInstance(new FirstPageFragmentListener()
{
public void onSwitchToNextFragment()
{
mFragmentManager.beginTransaction().remove(mFragmentAtPos0).commit();
mFragmentAtPos0 = NextFragment.newInstance();
notifyDataSetChanged();
}
});
}
return mFragmentAtPos0;
}
else
return SecondPageFragment.newInstance();
}
@Override
public int getCount()
{
return NUM_ITEMS;
}
@Override
public int getItemPosition(Object object)
{
if (object instanceof FirstPageFragment && mFragmentAtPos0 instanceof NextFragment)
return POSITION_NONE;
return POSITION_UNCHANGED;
}
}
public interface FirstPageFragmentListener
{
void onSwitchToNextFragment();
}
Надеюсь, это кому-нибудь поможет!