8

Ich habe ein neues Projekt mit der Template-Implementierung von Navigation Drawer Fragment und einer MainActivity eingerichtet.Navigation Drawer onNavigationDrawerItemSelected wurde vor MainActivity onCreate aufgerufen?

Es bietet mir die folgenden relevanten Methoden:

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

Mein MainActivity von einem Schuss Aktivität gestartet wird, die einen gespeicherten Zugriffstoken über die EXTRA_TOKEN bekommt.

Dies ist die Überschreibung der Artikel Navigationsleiste wählen Hörer im 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; 
    } 
} 

Es beginnt drei verschiedene Fragmente in Abhängigkeit von dem Element in der NavDrawer ausgewählt ist. Während die neuen Fragmente instanziiert werden, wird die token-Zeichenfolge in ihren Konstruktor übergeben, der in der Klasse des Fragments für die weitere Verwendung gespeichert wird.

Beim ersten Start der App scheint es jedoch, dass onNavigationDrawerItemSelected vor onCreate aufgerufen wird! Dies führt dazu, dass ich ein Nullwert-Token in die Fragmente übergebe, was dazu führt, dass sie alle durcheinander sind.

Wie ist das möglich? Wie ich es verstehe, sollte das NavigationDrawerFragment noch nicht eingerichtet worden sein!

Ich setze Haltepunkte sowohl auf onCreate als auch auf onNavigationDrawerItemSelected switch position = 0. onNavigationDrawerItemSelected wird tatsächlich vor onCreate getroffen.

Wie kann ich sicherstellen, dass das Token zuerst erhalten, bevor Sie versuchen, die onNavigationDrawerItemSelected zu behandeln?

Jede Hilfe wäre willkommen.

Antwort

1

Sie konnten die Absicht zu einem Konstruktor bewegen und Ihre Token dort speichern etwa so:

Intent i; 

...... 

public FragmentConstructor() { 

    i = getIntent(); 
    token = intent.getStringExtra(EXTRA_TOKEN); 

} 
+0

Hilfe bitte, wenn zum Beispiel intent.method() einen Kontextparameter hat. Wenn ein Context-Parameter vorhanden ist, erhält intent.method (context) einen Null-Kontext. –

10

Ich glaube, ich dies herausgefunden, wie es für jemanden mit mir geschieht, die dies suchen und kann das nicht finden Antworten.

Wenn Sie die Android Studio DrawerActivity verwenden, gibt es einen Standardcode, den sie für Sie erstellen. In diesem Code in der activity_main.xml oder dem XML-Code, den DrawerActivity als Inhaltsansicht definiert, gibt es ein Tag.

Wenn setContentView() in onCreate() aufgerufen wird, wird dieses Fragment automatisch erstellt und technisch wird onCreate() immer noch zuerst aufgerufen, aber dann wird die Methode onNavigationDrawerItemSelected() vor allem anderen in create aufgerufen. Da setContentView normalerweise oben gehalten wird, verursacht dies Probleme, wenn Sie versuchen, den Zustand der Fragmente in Ihrer Schublade zu speichern.

Verschieben Sie einfach jeden Code, der für savedInstanceBundle über setContentView() überprüft, und es wird das Problem beheben.

Beispiel mit Kommentaren:

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

} 
0

Was ich tun musste war es zu machen Arbeit zu überprüfen, ob die Seite vor der Ausführung 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

auch mit der Verwendung eines boolean geladen ist ich zustimmen Überprüfen Sie, ob onCreate() das Laden beendet hat. Mein einziger anderer Vorschlag ist, dass Sie für eine schnelle Lösung onSectionAttached (int-Nummer) verwenden können, um jedes ausgewählte Element zu verarbeiten anstatt onNavigationDrawerItemSelected.

Verwandte Themen