1

I have the following bottom navbar code to switch between 3 fragments:

public class MainActivity extends AppCompatActivity {

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            Fragment fragment = null;

            switch (item.getItemId()) {
                case R.id.navigation_home:
                    fragment = new HomeFragment();
                    break;

                case R.id.navigation_dashboard:
                    fragment = new DashboardFragment();
                    break;

                case R.id.navigation_notifications:
                    fragment = new NotificationsFragment();
                    break;

            }

            return loadFragment(fragment);
        }

    };

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

        loadFragment(new HomeFragment());


        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }

    private boolean loadFragment(Fragment fragment) {
        //switching fragment
        if (fragment != null) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.fragment_container, fragment)
                    .commit();
            return true;
        }
        return false;
    }
}

In the fragments there are RecyclerViews with lists. Every time I switch between the tabs (between fragments), it looks like the fragment is reloaded, and the lists jump to the top. I want to prevent that reloading so that the user stays on the same place in the list he viewed before switching fragments

pileup
  • 1
  • 2
  • 18
  • 45

2 Answers2

2

The problem is that you are creating a new instance every time. You can cache the instance like:

    private Fragment mHomeFragment = new HomeFragment();
    private Fragment mDashboardFragment = new DashboardFragment();
    private Fragment mNotificationsFragment = new NotificationsFragment();


    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        Fragment fragment = null;

        switch (item.getItemId()) {
            case R.id.navigation_home:
                fragment = mHomeFragment;
                break;

            case R.id.navigation_dashboard:
                fragment = mDashboardFragment;
                break;

            case R.id.navigation_notifications:
                fragment = mNotificationsFragment;
                break;

        }

        return loadFragment(fragment);
    }
Bruno Martins
  • 1,347
  • 2
  • 11
  • 32
  • Can you please tell me where is the statement in the above code that caches the `fragment`? – Stack Overflow Mar 19 '21 at 18:20
  • The instance is being created when the field is created, in your case you are creating the instance every time the onNavigationItemSelected is being called. – Bruno Martins Mar 20 '21 at 19:04
0

As we could see, you are always replace your fragment when clicks on bottom navigation, replace means previous fragment removes and state cleans. The solution is do not create your fragment each time and use attach/detach method for showing actual fragment. Here is already described about these methods.

Dmytro Ivanov
  • 1,260
  • 1
  • 8
  • 10