导航抽屉onNavigationDrawerItemSelected调用之前MainActivity onCreate?

我已经使用Navigation Drawer Fragment和MainActivity的模板实现安装了一个新项目。

它为我提供了以下相关的方法:

@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)); } 

我的MainActivity由启动活动,通过EXTRA_TOKEN得到一个保存的访问令牌。

这是MainAcitivity中的导航抽屉项目select监听器的覆盖:

 @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; } } 

它根据在NavDrawer中select哪个项目启动三个不同的片段。 在实例化新的片段时, tokenstring被传递到它的构造器中,该构造器保存在片段的类中供进一步使用。

然而,在应用程序的第一次启动,似乎onNavigationDrawerItemSelected之前调用onCreate ! 这导致我传递一个空值标记到片段,导致他们都搞砸了。

这怎么可能? 据我所知,NavigationDrawerFragment不应该被设置!

我在onCreateonNavigationDrawerItemSelected switch position = 0上设置断点。 onNavigationDrawerItemSelected确实是在onCreate之前命中的。

在尝试处理onNavigationDrawerItemSelected之前,如何确保获取令牌?

任何帮助,将不胜感激。

Solutions Collecting From Web of "导航抽屉onNavigationDrawerItemSelected调用之前MainActivity onCreate?"

我相信我知道了这一点,因为任何人search这个东西都找不到答案。

如果您使用Android Studio DrawerActivity,那么它们会为您创build样板代码。 在activity_main.xml中的这段代码中,或者DrawerActivity设置为其内容视图的XML,都有一个标签。

在onCreate()中调用setContentView()时,会自动创build这个片段,所以在技术上onCreate()仍然是首先被调用的,但是在创build之前调用onNavigationDrawerItemSelected()方法。 由于setContentView通常保持最高,所以当试图在抽屉中存储碎片的状态时会产生问题。

只需移动任何检查上面的setContentView()的savedInstanceBundle的代码,它将解决这个问题。

示例与评论:

 @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)); } 

你可以将意图转移到构造函数中,并像这样保存你的标记:

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

我不得不做的工作是检查页面是否已经加载之前执行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; } 

我也同意使用布尔值来检查onCreate()是否已经完成加载。 我唯一的build议是,为了快速修复,你可以使用onSectionAttached(int number)来处理选中的每个项目,而不是onNavigationDrawerItemSelected。