Replace fragment with another fragment inside ViewPager

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.

  • Which Android Priority Job Queue (Asynk Task, Multithreading) library would you recommend for Android?
  • SecurityException: Not allowed to start service Intent act=com.google.android.c2dm.intent.REGISTER
  • Using both cameras on android: “Fail to connect to camera service”
  • Render error in Android Studio 3.0 Layout Editor
  • accepting click events in RelativeLayout
  • Custom linting lib in android
  • 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!

  • How to receive serial data using android bluetooth
  • What kind of OCR Java library should I use in Android?
  • Why android gives warning on using size smaller than 12sp?
  • Android index out of bounds error with no application code in stack trace
  • Android Studio - “aidl is missing”… no, it's not
  • Android: Is there a way to implement the barcode scanner into an app?
  • 5 Solutions collect form web for “Replace fragment with another fragment inside ViewPager”

    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.

    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 the getItemPosition() 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.

    Shouldn’t your getItem statement be returning fragment4 for case 0 in some circumstances?

    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….

        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);
        }
    

    I then programmatically remove/add/rearrange the list items (fragments) then call on the handler

    mAdapter.notifyDataSetChanged()
    

    Please see my answer to a similar question about how to insert/replace tabs with a ViewPager and FragmentPagerAdapter.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.