6

Ho una navigazione a discesa nella barra delle applicazioni. Il problema è che quando passo a un altro frammento, poi faccio un cambio di orientamento, inserisce comunque il primo frammento, anche se penso che stia consegnando in modo correttoInstanceState. Il problema sembra essere che onNavigationItemSelected viene chiamato, quindi .. come gestirlo correttamente? Potrei fare la variabile savedInstanceState un campo, ma che si sente solo sbagliato ...Barra di navigazione di navigazione in basso - la modifica dell'orientamento inserisce il frammento errato in

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

}

risposta

2

Recentemente ho riscontrato questo problema pure. L'ho affrontato ignorando il metodo onRetainCustomNonConfigurationInstance sull'attività.

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

Nel mio onCreate sono stato poi in grado di implementare la seguente:

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

Infine ho aggiornato onNavigationItemSelected modo che conosceva mIsOrientationChange

@Override 
public boolean onNavigationItemSelected(int position, long id) { 
    if (!mIsOrientationChange) { 
     // real navigation selected logic   
    } 

    mIsOrientationChange= false; 

    return true; 
} 

Edit: ho avuto l'idea di implementalo dal seguente articolo per sviluppatori Android: http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject

+0

Ciao, quello che ho finito per fare era persistere l'indice dell'elemento selezionato nel menu a discesa nella sostanza salvata – urSus

+0

Anche io stavo facendo questo (in realtà ho memorizzato l'indice come SharedPreference in modo che potesse essere usato all'avvio dell'app se questo è stato aperto in un secondo momento quando non è più in esecuzione in memoria). Il problema che stavo affrontando è un po 'diverso in quanto il frammento visibile potrebbe iniziare un altro frammento di bambino. A rotazione tornerebbe al frammento genitore invece che al bambino, il codice sopra mi ha permesso di aggirare quel secondo problema. –

+0

Ciò causa la visualizzazione del frammento errato nel menu a discesa sulla barra delle azioni. – howettl

Problemi correlati