I have an Activity (MainActivity) with a DrawerLayout using a NavigationDrawerFragment as a navigation menu. In this NavigationDrawerFragment, on navigation item click, startActivity(intent to MainActivity with extra) is called to send an intent, received in onNewIntent, to MainActivity ; android:launchMode="singleTop" in the manifest ; to display the corresponding fragment. In onCreate, if saveInstanceState is not null, no fragment transaction is made because the current fragment will be automatically restored.
The problem is : for one fragment (not the others) : DashboardFragment, the one launched by default, on screen orientation, the fragment is restored but then recreated.
I can see that using the debugger : the regular process is called : Activity recreated, fragment restored correctly, then fragment recreated.
I can also see it in the FragmentManager logs (comparing behavior with another fragment) : the fragment is restored correctly but then, I can see a commit replacing the fragment with a new instance of DashboardFragment. In the code, I can't see where this commit would come from (I've put breakpoints in all the commits int the code and none is called).
Do you have any idea why this is happening ?
I can put code on request, this is a complex app, not open source, and I'm not sure which part to put here.
Simplified MainActivity :
public class MainActivity extends MeerkatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MeerkatApplication.get(this).getAppComponent().inject(this);
setContentView(R.layout.base_activity_layout_withdrawer);
setSupportActionBar(toolbar);
navigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigationMenu);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
toolbar,
R.string.open_drawer,
R.string.close_drawer);
drawerLayout.addDrawerListener(drawerToggle);
drawerLayout.setStatusBarBackground(R.color.primaryDarkColor);
drawerToggle.syncState();
final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowTitleEnabled(true);
}
//first calling before onNewIntent :
if (savedInstanceState == null) {
openFirstOpenableSection();
}
if (paneContainer != null) {
// Enable animation
LayoutTransition transition = new LayoutTransition();
transition.enableTransitionType(LayoutTransition.CHANGING);
paneContainer.setLayoutTransition(transition);
}
}
private void openFirstOpenableSection() {
int dc_id = -1;
if(getIntent() != null){
dc_id = getIntent().getIntExtra(EXTRA_DATACENTER_ID,-1);
}
int sectionToOpen = findFirstOpenableSection(sessionInformations
.getOrganizationInformations());
eventBus.post(new NavigationChangedEvent(sectionToOpen));
switch (sectionToOpen) {
case R.id.dashboard:
if(dc_id != -1){
IntentStarter.showDashAfterRequest(this,dc_id);
}else{
IntentStarter.showDashboard(this);
}
break;
...
default:
IntentStarter.showNoSectionAvailable(this);
}
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
Bundle extras = intent.getExtras();
if (extras != null) {
String showAction = intent.getStringExtra(EXTRA_SHOW_ACTION);
if (rightPane != null) {
rightPane.setVisibility(View.GONE);
}
switch (extras.getInt(EXTRA_MENU_ITEM, -1)) {
case EXTRA_MENU_ITEM_DASHBOARD:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, DashboardFragmentBuilder
.newDashboardFragment(sessionInformations.getUser().getId(),
getResources().getString(R.string.dashboard_personalDashboard),
"pda"), "DASHBOARD")
.commit();
}
drawerLayout.closeDrawer(GravityCompat.START);
break;
...
case EXTRA_MENU_ITEM_LOGOUT:
logout();
break;
default:
break;
}
}
}
IntentStarter :
public final class IntentStarter {
public static void showDashboard(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_MENU_ITEM, MainActivity.EXTRA_MENU_ITEM_DASHBOARD);
context.startActivity(intent);
}
}
NavigationDrawerFragment :
public class NavigationDrawerFragment extends MeerkatFragment {
#OnClick({R.id.dashboard, ... R.id.logout})
public void onMenuItemSelected(View view) {
switch (view.getId()) {
case R.id.dashboard:
desactivateAllViews();
IntentStarter.showDashboard(getActivity());
view.setActivated(true);
break;
case R.id.logout:
IntentStarter.logout(getActivity());
view.setActivated(true);
break;
...
}
}
}
Related
I've already searched about this and found nothing, which helps me to solve my problem. In my Code I have a SpaceNavigationView (like BottomNavigationView) with five Fragments.
So in Fragment A, I've put a Recyclerview. If an item of the Recyclerview gets clicked, it will replace the current fragment with a new child fragment B.
In Fragment B I've set a Chronometer, which should count the time, when it gets pressed.
Now if I switch from Fragment B to Fragment C and go back to Fragment B, the Chronometer starts by zero, because the fragment was replaced.
I've tried to used onSaveInstanceState, so that it can be called when Fragment is recreated, but this doesn't work for me.
Here's a piece of the HomeActivity, which includes all the Fragments.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
init();
setFragment(fragmentHome);
navigationView.initWithSaveInstanceState(savedInstanceState);
navigationView.addSpaceItem(new SpaceItem("", R.drawable.bottom_baby));
navigationView.addSpaceItem(new SpaceItem("", R.drawable.bottom_advise));
navigationView.addSpaceItem(new SpaceItem("", R.drawable.ic_favorite_black_24dp));
navigationView.addSpaceItem(new SpaceItem("", R.drawable.ic_settings));
navigationView.setSpaceOnClickListener(new SpaceOnClickListener() {
#Override
public void onCentreButtonClick() {
setFragment(fragmentPlayground);
navigationView.setCentreButtonSelectable(true);
}
#Override
public void onItemClick(int itemIndex, String itemName) {
switch (itemIndex) {
case 0:
setFragment(fragmentHome);
return;
case 1:
setFragment(fragmentAdvising);
return;
case 2:
setFragment(fragmentMemories);
return;
case 3:
setFragment(fragmentSettings);
return;
default:
setFragment(fragmentHome);
return;
}
}
#Override
public void onItemReselected(int itemIndex, String itemName) {
Toast.makeText(HomeActivity.this, itemIndex + " " + itemName, Toast.LENGTH_SHORT).show();
}
});
}
private void setFragment(Fragment fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.commit();
}
So if i navigate now to FragmentHome and use the OnClickListener for Reycleritems, I will switch to Fragment_Chronograph
#Override
public void onItemClick(int position) {
switch (position) {
case 0:
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment_chronograph).commit();
}
So now I'm in Fragment_Chronograph and want to save the base for Chronograph. I will save the variable in onSavedInstanceState, which gets called when Activity is Paused.
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
startTime = SystemClock.elapsedRealtime() - chronometerLeft.getBase();
outState.putLong(CHRONOLEFT_TIME_SAVE_ID,startTime);
super.onSaveInstanceState(outState);
#Override
public void onPause() {
super.onPause();
onSaveInstanceState(new Bundle());
}
At the end i've put this code for restore in the OnCreate Method:
if (savedInstanceState != null) {
startTime = savedInstanceState.getLong(CHRONOLEFT_TIME_SAVE_ID,0);
chronometerLeft.setBase(startTime - SystemClock.elapsedRealtime());
chronometerLeft.start();
The OnSaveInstanceState gets called, but in the OnCreate Method it won't be called. I would be very thankful if someone could help me with this problem. I'm searching for days and didnt get a solution.
in set fragment method , first find fragment with id and then check if it's not null replace that
Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_PLACEHOLDER);
if (fragment == null) {
fragment = new PlaceholderFragment();
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment, TAG_PLACEHOLDER)
.commit();
Note : you must add tag to your fragments
#Arvin
FragmentHome ist initiated in the init() method;
private void init() {
navigationView = findViewById(R.id.space);
fragmentHome = new FragmentHome();
fragmentAdvising = new FragmentAdvising();
fragmentMemories = new FragmentMemories();
fragmentSettings = new FragmentSettings();
fragmentPlayground = new FragmentPlayground();
============= UPDATE =================
Problem was solved. I didn't have to use OnSavedInstanceState. I used a Helperclass to store the variable of the Chronometerbase. In OnCreate method i check if the variable is not null, then restore the before saved base.
I have an app that I'm working on that uses the Twitter API. I have a list view of tweets inside of a Navigation Drawer activity that I added with Android Studio. I have another activity that I use for a settings activity, and on that activity the user can select the theme.
The problem I'm having is that when the user changes the setting and presses the back button, the theme of the container is changed, but not the fragment containing the list view. It's not until I restart the app that the proper theme is applied to the fragment.
However, if I use the back button on the action bar (up navigation) the theme is applied right away.
I'd like to come up with a way to apply the theme again right away when the user presses the back button (And the theme has actually been toggled), and so far this is what I've got:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case RETURN_TO_TWEET_LIST:
if (resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
if (bundle != null) {
boolean themeChanged = bundle.getBoolean(AppConstants.Strings.THEME_CHANGED);
if (themeChanged) {
refreshFragment();
}
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void refreshFragment() {
//TODO: Figure out how to get the list view to refresh when pressing back
}
I feel like the problem is not my Fragment code, as it works the way I would expect in one case, but no the other.
Here is the Navigation Drawer class:
public class CategoryViewSelector extends BaseActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
private TwitterFeedFragment currentFragment;
private String fragmentName = "CUSTOM_FRAGMENT";
private CategoryManager categoryManager;
private final int RETURN_TO_TWEET_LIST = 2;
private SettingsManager settingsManager;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
private String[] drawerItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
categoryManager = new CategoryManager();
setContentView(R.layout.activity_category_view_selector);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public void onNavigationDrawerItemSelected(int position) {
//create a fragment object palceholder
TwitterFeedFragment fragment = null;
// update the main content by replacing fragments
//create a bundle object that will be used to pass arguments to the fragment
//such as a category id.
Bundle bundle = new Bundle();
switch(position) {
case 0:
//load all the tweets by default.
bundle.putLong("categoryId", position);
fragment = new TwitterFeedFragment();
fragment.setArguments(bundle);
setCurrentFragment(fragment);
break;
case 1:
Intent intent = new Intent(this, CategoryManagerView.class);
//may have to change this to be for result again, so that you can use the onActivityResult method
//which will prevent refreshing of the fragment.
startActivityForResult(intent, RETURN_TO_TWEET_LIST);
break;
case 2:
Toast.makeText(getApplicationContext(), "Help not yet available", Toast.LENGTH_LONG).show();
break;
default:
openFragmentForCategory(position);
break;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, currentFragment, fragmentName)
.commitAllowingStateLoss();
}
private void openFragmentForCategory(int position) {
List<Category> categories = categoryManager.getAllCategories();
//there are three default items in the list right now.
//figure out a better way to handle this. Maybe an app constant.
int index = position - 3;
Category selectedCategory = categories.get(index);
long Id = selectedCategory.getId();
Bundle bundle = new Bundle();
TwitterFeedFragment fragment = null;
bundle.putLong("categoryId", Id);
bundle.putString("categoryName", selectedCategory.getCategoryName());
fragment = new TwitterFeedFragment();
fragment.setArguments(bundle);
setCurrentFragment(fragment);
}
/**
* This method attaches a title to the fragment window when an item is clicked. This will also
* require the use of the category names from the category manager.
* #param number
*/
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.text_category_default_feed);
break;
case 2:
mTitle = "";
break;
case 3:
mTitle = getString(R.string.text_category_help);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.menu_category_view_selector, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case R.id.action_settings:
Intent intent = new Intent(this, SettingsActivity.class);
startActivityForResult(intent, RETURN_TO_TWEET_LIST);
break;
case R.id.action_refresh:
currentFragment.refreshFeed();
break;
case R.id.action_logout:
TwitterApplication.getRestClient().clearAccessToken();
onBackPressed();
break;
}
return super.onOptionsItemSelected(item);
}
/**
* This is required so that the refreshFeed method of any fragment can be called.
*
* In the future it might make more sense to make an interface.
* #param currentFragment
*/
public void setCurrentFragment(TwitterFeedFragment currentFragment) {
this.currentFragment = currentFragment;
}
#Override
public void onBackPressed() {
Intent intent = new Intent();
setResult(RESULT_OK, intent);
super.onBackPressed();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case RETURN_TO_TWEET_LIST:
if (resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
if (bundle != null) {
boolean themeChanged = bundle.getBoolean(AppConstants.Strings.THEME_CHANGED);
if (themeChanged) {
refreshFragment();
}
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void refreshFragment() {
//TODO: Figure out how to get the list view to refresh when pressing back
}
}
Does anyone have suggestions on what I should be doing differently that would allow the fragment to have the correct theme when the back button is pressed? Please let me know if you would like to see more code, or have any questions.
I have tried detaching and attaching the fragment using the fragment manager, but I guess the theme of the fragment is never changed that way.
I'm also open to other suggestions for code improvement when they are spotted.
Thank you very much for any help!
You have to set an Activity's theme in onCreate() before calling setContentView(). And the fragment's theme is set during onCreateView().
What do you mean when you say the container changes theme, but not the fragment? I'm guessing this is what happens ...
1) you go into the SettingsActivity to change theme
2) The host Activity goes through onStop/onCreate, meaning it gets re-themed
3) but you have setRetainInstance(true) on the Fragment, meaning it does not get recreated.
If so, you have two options: remove setRetainInstance, or manually create a completely new Fragment (not just detach and re-attach) when you see that the theme has changed.
A quick fix would be to detach then re-attach the fragment.
Otherwise you could call invalidate() on the specific views of your fragment.
I have an Activity that contains a number of Fragments that are swapped based on the selected item in a Navigation Drawer. I am trying to retain the current fragment across an orientation change by calling setRetainInstance(true) on the Fragment and then checking if that fragment exists in onCreate(...). However, the Fragment is always null when I try to get it on onCreate(...). I've been banging my head against my desk for hours over this. Can anyone spot a problem?
Relevant parts of activity
public class StartActivity {
private static final String MAIN_FRAGMENT_TAG = "mainFragment";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
...
if(savedInstanceState != null) {
Fragment f = getSupportFragmentManager().findFragmentByTag(MAIN_FRAGMENT_TAG);
if(f == null) {
// FRAGMENT IS ALWAYS NULL
switchToModeForPosition(...);
} else {
setupActionBarForPosition(...);
}
} else {
// Default to events view
switchToModeForPosition(0);
}
}
private void switchToModeForPosition(int position) {
Fragment fragment;
switch (position) {
default:
case 0: //events
fragment = new EventsByWeekFragment();
setupActionBarForEvents();
break;
case 1: //teams
fragment = new AllTeamsListFragment();
setupActionBarForTeams();
break;
case 2: //insights
fragment = new InsightsFragment();
setupActionBarForInsights();
break;
case 3:
startActivity(new Intent(this, SettingsActivity.class));
mDrawerLayout.closeDrawer(mDrawerList);
return;
}
fragment.setRetainInstance(true);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, MAIN_FRAGMENT_TAG).commit();
}
}
use setRetainInstance(true)it in each Fragment class.
public void onCreated(Bundle savedInstanceState)
{
super.onCreated(savedInstanceState);
setRetainInstance(true);
}
Or
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
}
I'm new to android and have a "little" problem.
I'm starting the main activity which extend the base class.
The base class starts my "Navigation" class... and in the navigation class i have an switch argument to choose, wich activity should be created - well, at this moment i had an infinitie loop and i have noe idea why..
It works fine when i'm using fragments but i'm want to use activities... Hope someone can help me :)
Here is my code.
public class MainActivity extends Base {
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("boot", "MainActivity-onCreate");
super.onCreate(savedInstanceState);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, new MainFragment())
.commit();
}
Base
public class Base extends ActionBarActivity implements
NavigationDrawer.NavigationDrawerCallback {
public NavigationDrawer mNavigationDrawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("boot", "Base-onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the drawer
mNavigationDrawer = (NavigationDrawer)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mNavigationDrawer.setUp((DrawerLayout)findViewById(R.id.drawer_layout),
R.id.navigation_drawer);
}
Navigation
public class NavigationDrawer extends Fragment {
private ActionBarDrawerToggle mDrawerToggle;
private NavigationDrawerCallback mCallbacks;
private DrawerLayout mDrawerLayout;
private ListView mDrawerListView;
private View mFragmentContainer;
private boolean mUserLearnedNavigation;
private static final String PREF_USER_LEARNED_NAVI = "navigation_learned";
private static final String STATE_SELECTED_POSITION = "selected_position";
private int mCurrentSelectedPosition;
private boolean mFromSavedInstanceState;
#Override
public void onCreate(Bundle savedInstanceState) {
Log.v("boot", "Nav - onCreate");
super.onCreate(savedInstanceState);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedNavigation = sp.getBoolean(PREF_USER_LEARNED_NAVI, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
selectItem(mCurrentSelectedPosition);
} ...
private void selectItem(int position) {
Log.v("boot", "Nav - selectitem");
mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainer);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemClicked(position);
}
switch (position) {
case 0:
startActivity(new Intent(getActivity(), MainActivity.class));
break;
case 1:
startActivity(new Intent(getActivity(), ExpensesActivity.class));
break;
default:
startActivity(new Intent(getActivity(), MainActivity.class));
break;
}
}
Each time you start an activity, your menu get recreated and thus the switch case get executed. You shouldn't call selectItem in the onCreate of your menu. If you want to keep the user navigation, you'll have to start the proper activity in MainActivity.
You can add a check to see if getActivity is an instance of the activity you want to start before calling startActivity so you don't run in infinite loop again.
I am having a actionbar dropdown navigation. The problem is when I switch to a different fragment, then do an orientation change, it puts the first fragment inside anyways, even though I think I am handing savedInstanceState correctly. The problem seems to be that onNavigationItemSelected gets called, so .. how would I correctly handle this? I could make the savedInstanceState variable a field, but that just feels wrong...
public class MainActivity extends FragmentActivity implements MyListFragment.OnArticleSelectedListener {
public static final String TAG = "MainActivity";
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState != null) {
Fragment savedFragment = getSupportFragmentManager().getFragment(savedInstanceState, "saved_fragment");
Log.d(MainActivity.TAG, "savedInstanceState != null: " + savedFragment.getTag());
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, savedFragment, savedFragment.getTag())
.commit();
} else {
Log.d(MainActivity.TAG, "savedInstanceState == null");
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, new MyListFragment(), MyListFragment.TAG)
.commit();
}
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
String[] array = new String[] { "Inzeráty", "Dummy frag" };
SpinnerAdapter mSpinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item,
array);
actionBar.setListNavigationCallbacks(mSpinnerAdapter, new ActionBar.OnNavigationListener() {
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
Log.d(MainActivity.TAG, "onNavitagionItemSelected");
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
switch(itemPosition) {
case 0:
transaction.replace(R.id.fragment_container, new MyListFragment(), MyListFragment.TAG);
break;
case 1:
transaction.replace(R.id.fragment_container, new MyDummyFragment(), MyDummyFragment.TAG);
break;
}
transaction.commit();
return true;
}
});
}
#Override
public void onArticleSelected(Bundle bundle) {
Log.d(MainActivity.TAG, "MainActivity # onArticleSelected");
Intent intent = new Intent(this, DetailActivity.class);
intent.putExtras(bundle);
startActivity(intent);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
Log.d(MainActivity.TAG, "MainActivity # onSaveInstanceState: " + currentFragment.getTag());
getSupportFragmentManager().putFragment(outState, "saved_fragment", currentFragment);
super.onSaveInstanceState(outState);
}
}
I recently encountered this problem as well. I addressed it by overriding the onRetainCustomNonConfigurationInstance method on the activity.
#Override
public Object onRetainCustomNonConfigurationInstance() {
// return true so that onCreate will know it is an orientation change
return true;
}
In my onCreate I was then able to implement the following:
...
Object lastCustomNonConfigurationInstance = getLastCustomNonConfigurationInstance();
if (lastCustomNonConfigurationInstance != null) {
mIsOrientationChange = (Boolean) getLastCustomNonConfigurationInstance();
}
...
Lastly I updated onNavigationItemSelected so that it knew about mIsOrientationChange
#Override
public boolean onNavigationItemSelected(int position, long id) {
if (!mIsOrientationChange) {
// real navigation selected logic
}
mIsOrientationChange= false;
return true;
}
Edit: I got the idea to implement this from the following Android Developer article: http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject