How to Stop Fragment from Reloading When Changing Tabs?

Viewed 675

I have an Activity with a BottomNavigationView, which consists of 4 Fragments, the Fragments reload whenever I change tabs, this is my Activity's code

public class MainHomeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_home);

        BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
        bottomNavigationView.setOnNavigationItemSelectedListener(navigationItemSelectedListener);
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment()).commit();

    }

    private BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull @NotNull MenuItem item) {
            Fragment selectedFragment = null;

            switch (item.getItemId()){
                case R.id.nav_home:
                    selectedFragment = new HomeFragment();
                    break;
                case R.id.nav_list:
                    selectedFragment = new UsersFragment();
                    break;
                case R.id.nav_profile:
                    selectedFragment = new ProfileFragment();
                    break;
                case R.id.nav_settings:
                    selectedFragment = new SettingsFragment();
                    break;
            }

            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit();

            return true;
        }
    };
}

In the Fragments im loading data from parse I know that the mistake im doing is that I'm creating a new instance of the Fragment whenever I switch tabs, but I do not how to fix it or where to start from I saw some people saying that a ViewPagerAdapter should be used in this case but i cant manage to find a place where its explained properly.

Any assistance would be very appreciated!

3 Answers

Here's an article which describes your case perfectly and in detail.

Basically, it creates a fragment for each tab in memory, and saves them as a local variable in the activity:

final Fragment fragment1 = new HomeFragment();
final Fragment fragment2 = new DashboardFragment();
final Fragment fragment3 = new NotificationsFragment(); 
final FragmentManager fm = getSupportFragmentManager();
Fragment active = fragment1;

You add all 3 fragments to the manager, but hide 2 of them, so only 1 will be visible:

fm.beginTransaction().add(R.id.main_container, fragment3, "3").hide(fragment3).commit();
fm.beginTransaction().add(R.id.main_container, fragment2, "2").hide(fragment2).commit();
fm.beginTransaction().add(R.id.main_container,fragment1, "1").commit();

You implement the OnNavigationItemSelectedListener of the BottomNavigationView, check which item was pressed, and then show that fragment while hiding the previous:

case R.id.navigation_dashboard:
    fm.beginTransaction().hide(active).show(fragment2).commit();
    active = fragment2;

Instead of replacing the fragment, use add/remove and create a mechanism for adding and removing fragment stack, also it is not recommended but for the sake of question you can create a singleton fragment, instead of using a new Keyword everything tab is changed, along with that you can have a look at pageOffSet

 companion object{
          private lateinit var INSTANCE?: HomeFragment() = null
    }

  fun getInstance(): HomeFragment(){
         if(INSTANCE == null){
            INSTANCE = HomeFragment()
          }
    return INSTANCE 
  }

As we know the ViewPager recreates the fragments when we switch the pages with our BottomNavigationView. I know how to prevent this, use one of these 2 Options:

  1. As i can see your amount of fragments is small and fixed, add in your onCreate() of your

MainHomeActivity.java:

mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(limit);         //limit is a fixed integer
  1. Use a FragmentPagerAdapter as part of your ViewPager. (example provided in link)

UPDATE

In @moalzoabi's case the 2nd option worked. Follow along this post.

Related