I'm doing an app that is using fragments with a bottom navigation view and I've encountered a quite troublesome issue. For instance, let's say that I'm on the setting page which is the third fragment which is linked to the third icon of the bottom navigation view.
When I exit my app and use another one which means that my app is in the background (for instance I'm watching a video on youtube). When I go back to my app after a while it gets recreated, I notice that the fragment displayed will not be the one I was on when exiting the app (the first fragment gets displayed) but the active icon on the bottom navigation view is the still the one I was on before leaving the app (setting icon).
I was wondering if there's was a way to make sure that my fragment would be correctly attached to its bottom navigation icon if ever the application get recreated.
here's my code for displaying and linking the fragments to the botom navigation view:
public class HomeActivity extends LocalizationActivity {
final Fragment fragment1 = new CustomFragment();
final Fragment fragment2 = new ReportFragment();
final Fragment fragment3 = new UploadFragment();
final Fragment fragment4 = new SettingFragment();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = fragment1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//Setting the bottom navigation view
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
fm.beginTransaction().add(R.id.main_container, fragment4, "4").hide(fragment4).commit();
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();
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= item -> {
switch (item.getItemId()) {
case R.id.navigation_home:
fm.beginTransaction().hide(active).show(fragment1).commit();
active = fragment1;
return true;
case R.id.navigation_report:
fm.beginTransaction().hide(active).show(fragment2).commit();
active = fragment2;
return true;
case R.id.navigation_backup:
fm.beginTransaction().hide(active).show(fragment3).commit();
active = fragment3;
return true;
case R.id.navigation_setting:
fm.beginTransaction().hide(active).show(fragment4).commit();
active = fragment4;
return true;
}
return false;
};
}
I found out that my problem was related to the lifecycle of the fragments, when the activity is recreated, the same process was being done again even though the icon selected on the bottom navigation is somehow saved, I noticed that the active fragment was also saved but was constantly erased because of the code so I came up with this :
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
if(savedInstanceState == null){
fm.beginTransaction().add(R.id.main_container, fragment4, "4").hide(fragment4).commit();
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();
} else{
fm.beginTransaction().add(R.id.main_container, fragment4, "4").hide(fragment4).commit();
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").hide(fragment1).commit();
}
//Setting the bottom navigation view
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
On the first launch savedInstanceState is null so the fragments are added accordingly, Even if you don't override onSaveInstanceState in the activity, the savedInstanceState parameter will still be non-null when restoring an Activity. It'll just be an empty Bundle. Thus, you can use this to hide the other fragments so that the active fragment will be showed when the activity is recreated.