I found many post explaining how get the Fragment
from the savedInstanceState
Bundle
but, because the Activity
can swap between 4 Fragments
, i need a way to know which Fragment was alive before rotate when the orientation started to change.
The reason i have several Fragments is because i am using Navigation Drawer, so each menu item as a fragment.
I had the same issue and I fixed it adding this to the Navigation Drawer activity code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null){
//Handle the initial fragment transaction
}
...
}
For example, I have a navigation drawer with "Home", "Settings" and "About" as menu items, each with a fragment "home_fragment", "settings_fragment" and "about_fragment".
If I want "home_fragment" to appear when the navigation drawer activity launches, I use this code on the OnCreate function:
FragmentManager fM = getSupportFragmentManager();
fM.beginTransaction().replace(R.id.NavDrawContent,new home_fragment()).commit();
But I want it to execute only when (savedInstanceState == null), so that when we change the phone orientation while in settings_fragment (for example), it doesn't inflate home_fragment.
So the final code (inside the navigation drawer activity OnCreate):
super.onCreate(savedInstanceState);
if(savedInstanceState==null){
FragmentManager fM = getSupportFragmentManager();
fM.beginTransaction().replace(R.id.NavDrawContent,new home_fragment()).commit();
}
In the activity, you save the fragment's instance in onSaveInstanceState()
and restore in onCreate()
.
@Override
public void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
fragment = getSupportFragmentManager().getFragment(savedInstanceState, "KEY");
changeFragment(fragment, "MY TAG")
} else {
setupFragment();
}
...
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Fragment fragment = getSupportFragmentManager().findFragmentByTag("MY TAG");
if (fragment != null) {
getSupportFragmentManager().putFragment(outState, "KEY", fragment);
}
}
If you need to know which fragment was saved, you can check with instanceof
, for example:
if (fragment instanceof SettingsFragment) {
// ...
}
Found my own answer and it it was a really simple thing after all. I left the solution here for those who are not familiar to android,like me .
//current fragment
int fragment_id;
//make fragment selection available form the menu resource id
private void setFragment(MenuItem item) {
Fragment fragment = null;
fragment_id = item.getItemId();
switch (fragment_id) {
case R.id.nav_option_1:
fragment = MyFragment1.newInstance(true);
break;
...
//Set fragment
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.content_navigation, fragment);
t.commit();
}
item.setChecked(true);
}
private class DrawerItemClickListener implements NavigationView.OnNavigationItemSelectedListener {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
setFragment(item);
return false;
}
}
//save the state
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SAVE_INSTANCE_FRAGMENT_KEY, fragmentid);
}
//restore the saved fragment on create
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation);
///...
if (savedInstanceState != null) {
int fragment_id = savedInstanceState.getInt(SAVE_INSTANCE_FRAGMENT_KEY);
selectItem(mDrawerList.getMenu().findItem(fragment_id));
} else {
selectItem(mDrawerList.getMenu().findItem(R.id.home_fragment_id));
}
}