I am trying to simulate App (screen) rotate, but after the screen is rotated, the BottomNavigation fragments won't work anymore.
I have the following Array / vars
private Fragment[] fragments = new Fragment[]{new HomeFragment(), new MapFragment(), new SavedFragment(), new NotificationsFragment()};
private int selected = -1;
In onCreateView
I am calling...
// open first Fragment when app starts
if (savedInstanceState == null) switchFragment(0, ShoutsHomeFragment.TAG);
else selected = savedInstanceState.getInt(SELECTED_FRAGMENT);
switchFragment
looks like
private void switchFragment(int index, String tag) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
// creating for the first time
if (fragment == null) transaction.add(R.id.tab_fragment_container, fragments[index], tag);
if (selected >= 0) transaction.hide(fragments[selected]); // <--- don't work
if (fragment != null) transaction.show(fragment); // <--- don't work
transaction.commit();
selected = index;
}
So, transaction.hide
and transaction.show
is not working after rotating the screen, it stays on the same Fragment when I tap on other items on the BottomNavigation
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_shouts_home:
switchFragment(0, HomeFragment.TAG);
return true;
case R.id.navigation_heat_map:
switchFragment(1, MapFragment.TAG);
return true;
case R.id.navigation_loved:
switchFragment(2, SavedFragment.TAG);
return true;
case R.id.navigation_notifications:
switchFragment(3, NotificationsFragment.TAG);
return true;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putInt(SELECTED_FRAGMENT, selected);
super.onSaveInstanceState(outState);
}
I programmed it this way so that I can retain Fragments (scroll) position when switching between items on BottomNavigation. So I want to show/hide
instead of creating new Instance every time. Any help is appreciated.
When you rotate the screen, all of your activities and all of your non-retained fragments are put through the whole lifecycle. This means your private Fragment[] fragments...
is also recreated. Your Fragments in your list are no longer the fragments in the FragmentManager
. This means hide is not going to work the way you have it being called and the top-most Fragment will always be the one that is visible. If you use the TAG method, it will probably work.
String getFragmentTagByIndex(final int index) {
switch (index) {
// Make return tag.
}
}
{
// inside switchFragment
final Fragment visibleFragment = transaction.findFragmentByTag(getFragmentTagByIndex(selected));
transaction.hide(visibleFragment);
}
You are essentially trying to implement a ViewPager
with a FragmentPagerAdapter I would recommend you use the FragmentPagerAdapter