2

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!

Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
moalzoabi
  • 27
  • 8

3 Answers3

1

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;
Daniel Zolnai
  • 16,487
  • 7
  • 59
  • 71
  • Works like a charm, tysm! – moalzoabi Jul 23 '21 at 15:02
  • heyo, a quick question, in terms of the code that you answered me with, do you by any chance know how I can reload the fragment when a tab is reselected? – moalzoabi Jul 24 '21 at 10:23
  • You set the setOnNavigationItemReselectedListener on the BottomNavigationView, and then can call a reload() method on `active`. Make sure to use a base (abstract) class for all fragments, which has this method, so you can call it. – Daniel Zolnai Jul 24 '21 at 10:32
  • You could also try: FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.detach(active); fragmentTransaction.attach(active); fragmentTransaction.commit(); – Daniel Zolnai Jul 24 '21 at 10:33
  • the second way didn't work sadly could you please be more clear on what you said for the first solution you provided? I'm still kinda of a newbie so any clarification would be very much appreciated! – moalzoabi Jul 24 '21 at 15:21
  • Set the listener and put the code in that part. Note that this is not the same listener as in my original answer – Daniel Zolnai Jul 24 '21 at 16:01
  • yes I know, I did implement `OnNavigationItemReselectedListener` and set it to my navigation bar, to no avail unfortunately – moalzoabi Jul 24 '21 at 18:45
0

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 
  }
Ali
  • 519
  • 4
  • 13
0

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.

Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
  • I'm still new-ish to android so please bear with me as I'm lost, what is `.pager` in my case? also, as for the `FragmentPageAdapter` how should I apply it in my case? I read the doc but I have no clue as to where to start if needed I can provide my fragments codes if that helps, even though they're a mess – moalzoabi Jul 23 '21 at 04:04
  • Update: managed to find a solution that worked for me https://stackoverflow.com/a/60201555/16477537 but now Im facing another problem, is that when i change the UI mode to dark or night and then switch tabs, my app bugs out and the tabs start to overlap each other would you by any chance a reason or a solution? – moalzoabi Jul 23 '21 at 06:57
  • Alright, glad you found a solution on that. What do you mean with overlap? Do you meant that the night mode won't apply and saved on every site? Need a bit more detail on that. I add your link in the answer to make clear what helped in your case. – Ole Pannier Jul 23 '21 at 12:36
  • basically what happens is that when I change the ui mode, and switch tabs, the previous tab remains in the back, its like the fragments are overlapping each other with copies, not active ones though, just a static "picture" of how the previous fragment looked like before I went to another one – moalzoabi Jul 23 '21 at 15:05
  • I suggest to write a new question and provide your new code (that involve the solution of the main question of this post). Link me the new question, here. A subquestion is too confusing. – Ole Pannier Jul 23 '21 at 15:12
  • I figured it out, or at least temporarily did, thank you for keeping up with me when or if I post a question regarding the problem I had I'll be sure to reply here, thank you again! – moalzoabi Jul 24 '21 at 10:32