8

Mam nowy projekt z szablonem implementacji Fragmentu szuflady nawigacji i MainActivity.Nawigacja szuflady naNavigationDrawerItemSelected wywołana przed MainActivity onCreate?

Zapewnia mnie z następujących odpowiednich metod:

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

Moja główną działalność rozpoczyna działalność powitalny, który ją zapisaną token dostępu poprzez EXTRA_TOKEN.

To jest przesłanianie z szuflady nawigacji pozycji Wybierz słuchacza w 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; 
    } 
} 

Zaczyna trzy różne fragmenty w zależności, który element jest zaznaczony w NavDrawer. Podczas tworzenia nowych fragmentów, ciąg token jest przekazywany do jego konstruktora, który jest zapisywany w klasie fragmentów do dalszego wykorzystania.

Jednak przy pierwszym uruchomieniu aplikacji wygląda na to, że onNavigationDrawerItemSelected jest wywoływana przed onCreate! To powoduje, że przechodzę do fragmentów znacznika wartości pustej, powodując, że wszystkie są pomieszane.

Jak to jest możliwe? Jak już rozumiem, NavDrawerFragment nie powinien być jeszcze skonfigurowany!

Ustawiam punkty przerwania zarówno na onCreate, jak i na onNavigationDrawerItemSelected switch position = 0. onNavigationDrawerItemSelected rzeczywiście jest trafiony przed onCreate.

Jak mogę się upewnić, że najpierw otrzymam token, zanim spróbuję obsłużyć onNavigationDrawerItemSelected?

Każda pomoc zostanie doceniona.

Odpowiedz

1

Można przesunąć zamiar konstruktora i zapisać znaki tam tak:

Intent i; 

...... 

public FragmentConstructor() { 

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

} 
+0

Pomoc proszę, gdy na przykład intent.method() ma parametr Context. Gdy istnieje parametr Context, intent.method (kontekst) otrzymuje zerowy kontekst. –

10

wierzę zorientowaliśmy się, jak to się dzieje ze mną dla każdego, kto szuka tego i nie mogę znaleźć odpowiedź.

Jeśli korzystasz z aplikacji Studio Studio DrawerActivity, jest tworzony dla Ciebie kod na płycie głównej. W tym kodzie w pliku activity_main.xml lub w jakimkolwiek formacie XML ustawionym przez kreator szuflady jako "widok zawartości" znajduje się tag.

Po wywołaniu funkcji setContentView() w onCreate() ten fragment jest tworzony automatycznie i technicznie metoda onCreate() jest wciąż wywoływana jako pierwsza, a następnie metoda onNavigationDrawerItemSelected() jest wywoływana przed cokolwiek innego w procesie tworzenia. Ponieważ ustawienie setContentView jest zwykle utrzymywane na najwyższym poziomie, powoduje to problemy podczas próby przechowywania stanu fragmentów w szufladzie.

Po prostu przenieś dowolny kod, który sprawdza dla savedInstanceBundle powyżej setContentView(), a to rozwiąże problem.

Przykład z komentarzem:

@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

Co miałem zrobić, aby praca była sprawdzić, czy strona jest ładowany przed wykonaniem 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

Zgadzam się również z użyciem logiczną do sprawdź, czy zakończono ładowanie onCreate(). Moją jedyną sugestią jest to, że dla szybkiej poprawki można użyć onSectionAttached (numer int) do przetworzenia każdego wybranego elementu zamiast ONNavigationDrawerItemSelected.

Powiązane problemy