ActionBar Drop Down Navigation - Changing the orientation puts the wrong fragment in

I have a drop down list of actions in the taskbar. The problem is that when I switch to another fragment and then change the orientation, it puts the first fragment inside, although I think I pass savedInstanceState correctly. The problem is that onNavigationItemSelected gets called, so ... how would I handle this correctly? I can make the savedInstanceState variable a field, but this is just 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); } 

}

+6
source share
1 answer

I recently ran into this problem. I accessed it by overriding the onRetainCustomNonConfigurationInstance method in activity.

 @Override public Object onRetainCustomNonConfigurationInstance() { // return true so that onCreate will know it is an orientation change return true; } 

In my onCreate I was able to implement the following:

 ... Object lastCustomNonConfigurationInstance = getLastCustomNonConfigurationInstance(); if (lastCustomNonConfigurationInstance != null) { mIsOrientationChange = (Boolean) getLastCustomNonConfigurationInstance(); } ... 

Finally, I updated onNavigationItemSelected so that it knows 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

+2
source

All Articles