The onNavigationDrawerItemSelected navigation box is called before MainActivity onCreate?

I have a new project with the implementation of the navigation box fragment template and MainActivity.

It provides me with the following relevant methods:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = getIntent(); token = intent.getStringExtra(EXTRA_TOKEN); mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer); mNavigationDrawerFragment.activityMain = this; mTitle = getTitle(); // Set up the drawer. mNavigationDrawerFragment.setUp( R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout)); } 

My MainActivity is triggered by a burst activity that receives the saved access token through EXTRA_TOKEN.

This is an override of the Navigation Box item selector in MainAcitivity:

 @Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getSupportFragmentManager(); onSectionAttached(position + 1); switch(position) { case 0: fragmentManager.beginTransaction() .replace(R.id.container, FeedFragment.newInstance(token, "")) .commit(); break; case 1: fragmentManager.beginTransaction() .replace(R.id.container, PeopleFragment.newInstance("", "")) .commit(); break; case 2: if(qbloggedin) { fragmentManager.beginTransaction() .replace(R.id.container, MessagesFragment.newInstance(token, "")) .commit(); } break; default: break; } } 

It launches three different fragments, depending on which element is selected in NavDrawer. When creating new fragments, the token string is passed to its constructor, which is stored in the fragment class for future use.

However, when you first start the application, it seems that onNavigationDrawerItemSelected is called before onCreate ! This leads to the fact that I pass the token of zero value to the fragments, causing them to get mixed up.

How is this possible? As far as I understand, the NavigationDrawerFragment function has not yet been configured!

I set breakpoints on both onCreate and onNavigationDrawerItemSelected switch position = 0 . onNavigationDrawerItemSelected really hit before onCreate .

How can I make sure to get the token first before trying to handle onNavigationDrawerItemSelected ?

Any help would be appreciated.

+8
java android android-intent android-fragments navigation-drawer
source share
4 answers

I believe that I understood this, because it happened to me for everyone who is looking for it and can not find the answer.

If you are using Android Studio DrawerActivity, then there is the boilerplate code that they create for you. There is a tag in this code in the activity_main.xml file or any other XML that your DrawerActivity sets as its "content view".

When setContentView () is called in onCreate (), this snippet is created automatically, and so technically onCreate () is still called first, but then the onNavigationDrawerItemSelected () method is called before anything else in create. Since setContentView is usually supported at the top, this causes problems when trying to save the state of fragments in your inbox.

Just move any code that checks for savedInstanceBundle above setContentView () and it will fix the problem.

An example with comments:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // THIS IS WHERE YOU CHECK FOR SAVED INSTANCE // Check for frag if (savedInstanceState != null) { Log.i(TAG, "Get QuestionDayFragment"); mQuestionDaysFragment = (QuestionDaysFragment) getSupportFragmentManager().getFragment(savedInstanceState, QUESTION_DAY_FRAGMENT); } // View injection setContentView(R.layout.activity_main); ButterKnife.inject(this); // THIS IS WHERE THE CODE WAS BEFORE // THIS WOULD BE CALLED AFTER onNavigationDrawerItemSelected() // Singleton injection LifeboxApplication.graph().inject(this); // Toolbar setSupportActionBar(mToolbar); // FB uiHelper = new UiLifecycleHelper(this, callback); uiHelper.onCreate(savedInstanceState); // Drawer mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer); mTitle = getTitle(); mNavigationDrawerFragment.setUp(R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout)); } 
+10
source share

You can transfer the intention to the constructor and save your tokens there like this:

 Intent i; ...... public FragmentConstructor() { i = getIntent(); token = intent.getStringExtra(EXTRA_TOKEN); } 
+1
source share

I needed to do this to check if the page loaded before doing onNavigationDrawerItemSelected

  private Boolean loaded=false; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Your code here this.loaded=true; } public void onNavigationDrawerItemSelected(int position) { if (!this.loaded){ return; } 
0
source share

I also agree using a boolean to check if onCreate () has finished loading. My other suggestions are that for a quick fix, you can use onSectionAttached (int number) to process each selected item instead of onNavigationDrawerItemSelected.

0
source share

All Articles