Заменить фрагмент другим фрагментом внутри ViewPager
Я использую ViewPager вместе с FragmentPagerAdapter для размещения трех разных фрагментов
[Fragment1][Fragment2][Fragment3]
То, что я пытаюсь достичь, - это успешно заменить Fragment1 на новый фрагмент Fragment4, если удастся выполнить конкретную задачу.
Когда я использую..
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment1_layout_id, fragment4);
transaction.commit();
.. фрагмент заменяется красиво, а Fragment4 показан вместо Fragment1. Хотя, как только я провёл весь путь до Fragment3, а затем вернулся к Fragment4, Fragment1 сделал возвращение.
Тогда опять, если я использую..
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment1);
transaction.commit();
.. Fragment1 удаляется, и когда я возвращаюсь, Fragment4 есть. Таким образом, проблема с этим решением заключается в том, что я не мог найти способ сразу показать Fragment4, поскольку Fragment1 удален, даже если я попытался:
transaction.add(fragment4);
transaction.show(fragment4);
И вот как выглядит моя реализация FragmentPagerAdapter на данный момент без управления транзакциями:
public static class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return VIEW_COUNT;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = Fragment1.newInstance(context_);
break;
case 1:
fragment = Fragment2.newInstance(context_);
break;
case 2:
fragment = Fragment3.newInstance(context_);
break;
default:
break;
}
return fragment;
}
}
Изменить.
Так кажется, что я не совсем понял свой вопрос. Я решил удалить все спагетти, которые мне удалось создать раньше, и попытался указать, что я их оставил (см. Текст выше).
В любом случае, здесь почти что я пытаюсь сделать внутри getItem():
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
if (!app.isUserLoggedIn) {
if (loginFragment_ == null) {
loginFragment_ = LoginFragment.newInstance(context_);
transaction_ = fragmentManager_.beginTransaction();
if (logoutFragment_ != null) {
transaction_.remove(logoutFragment_);
logoutFragment_ = null;
}
transaction_.add(loginFragment_, "login");
transaction_.commit();
}
if (fragmentManager_.findFragmentByTag("login") == null)
fragment = LoginFragment.newInstance(context_);
else
fragment = fragmentManager_.findFragmentByTag("login");
} else {
if (logoutFragment_ == null) {
logoutFragment_ = LogoutFragment.newInstance(context_);
transaction_ = fragmentManager_.beginTransaction();
if (loginFragment_ != null) {
transaction_.remove(loginFragment_);
loginFragment_ = null;
}
transaction_.add(logoutFragment_, "logout");
transaction_.commit();
}
if (fragmentManager_.findFragmentByTag("logout") == null)
fragment = LogoutFragment.newInstance(context_);
else
fragment = fragmentManager_.findFragmentByTag("logout");
}
break;
case 1:
fragment = HomeFragment.newInstance(context_);
break;
case 2:
fragment = RegisterFragment.newInstance(context_);
break;
default:
break;
}
return fragment;
}
С этим кодом я ничего не делаю, но если кто-то увидит, что я делаю неправильно, и хотел бы указать мне в правильном направлении, я был бы признателен за это!
Ответы
Ответ 1
Попробуйте использовать FragmentStatePagerAdapter
http://android-developers.blogspot.com/2011_08_01_archive.html
coz он удалит фрагмент при прокрутке через представление (также когда вы вызываете getitem), поэтому вам не нужно явно удалять их самостоятельно.
У меня была та же проблема, что и для меня.
Я пробую ваш код и удаляю блок if (fragment!=null)
, и он работает.
Ответ 2
Как сказал Мауриси, вам нужно позвонить mAdapter.notifyDataSetChanged()
всякий раз, когда вы хотите сообщить ViewPager, что фрагменты были заменены. Однако вам также необходимо переопределить абстрактную функцию getItemPosition()
в вашем адаптере и вернуть POSITION_NONE при вызове со старым, скрытым, фрагментом в качестве аргумента. В противном случае ViewPager сохранит все текущие фрагменты.
Для получения дополнительной информации и кода примера см. этот ответ в вопросе .
Ответ 3
Должен ли ваш оператор getItem
возвращать фрагмент4 для case 0
в некоторых случаях?
Ответ 4
Эй, я решил эту проблему, используя List внутри моего FragmentPagerAdapter для обработки различных фрагментов, а затем мой getItem так же...
public void addScreen(String tag, Class<?> clss, Bundle args){
if(clss!=null){
TabInfo info = new TabInfo(tag, clss, args);
screens.add(info);
}
}
@Override
public Fragment getItem(int position) {
TabInfo info = screens.get(position);
return Fragment.instantiate(context, info.clss.getName(), info.args);
}
Затем я программно удаляю/добавляю/переупорядочиваю элементы списка (фрагменты), затем вызываю обработчик
mAdapter.notifyDataSetChanged()
Ответ 5
Обратите внимание на мой ответ на аналогичный вопрос о том, как вставлять/заменять вкладки с помощью ViewPager
и FragmentPagerAdapter
.