I'm using a ViewPager together with a FragmentPagerAdapter to host three different fragments
[Fragment1][Fragment2][Fragment3]
What I'm trying to achieve is to successfully replace Fragment1 with a whole new fragment, Fragment4, if a specific task succeeds.
When I use..
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment1_layout_id, fragment4);
transaction.commit();
..the fragment is replaced beautifully and Fragment4 is shown instead of Fragment1. Though as soon as I swipe all the way to Fragment3 and then back to Fragment4, Fragment1 has made a comeback.
Then again, if I use..
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment1);
transaction.commit();
..Fragment1 is removed and when I come back Fragment4 is there. So the problem with this solution is that I couldn't find a way to immediately show Fragment4 as Fragment1 is removed, even if I tried:
transaction.add(fragment4);
transaction.show(fragment4);
And here's how my FragmentPagerAdapter implementation looks like at the moment, without any transaction managing:
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;
}
}
Edit.
So it seems like I wasn't totally clear with my question. I decided to remove all the spaghetti I managed to create earlier and tried to state that I had left them off (see bolded text above).
Anyway here's pretty much what I have been trying to do inside 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;
}
With this code I get nothing done, but if someone sees what I'm doing wrong and would like to point me in the correct direction, I'd appreciate it a lot!
Hey I have solved this problem by using a List inside my FragmentPagerAdapter to handle the various fragments and then my getItem is like so....
I then programmatically remove/add/rearrange the list items (fragments) then call on the handler
Like Maurycy said, you need to call
mAdapter.notifyDataSetChanged()
whenever you want to tell the ViewPager that the fragments have been replaced. However, you also need to override thegetItemPosition()
abstract function in your adapter and return POSITION_NONE when called with an old, to be hidden, fragment as argument. Otherwise, ViewPager will retain all current fragments.For more information and example code, see this answer to a related question.
Try setting offScreenPageLimit to 5 (or based on your usecase) to avoid reloading of the fragment so that what you had replaced will stay instead of getting reloaded when you swipe.
Please see my answer to a similar question about how to insert/replace tabs with a
ViewPager
andFragmentPagerAdapter
.Shouldn't your
getItem
statement be returning fragment4 forcase 0
in some circumstances?Try using FragmentStatePagerAdapter
http://android-developers.blogspot.com/2011_08_01_archive.html
coz it will remove the fragment as you swipe through the view(also when you call getitem), so you don't need to explicitly remove them yourself.
I've been having the same problem it works for me.
I try your code and remove the
if (fragment!=null)
block and it works.