2012-03-01 14 views
11

sto sviluppando per Android 3+barra d'azione androide onNavigationItemSelected

Nella mia barra delle operazioni ho un elenco a discesa (vedi how to hide/unhide the actionbar list on android 3? per la discesa ho intenzione). Il problema è che ho bisogno di fare una certa azione quando l'utente seleziona qualcosa, ma Android chiama onNavigationItemSelected() come soons mentre disegna la vista, quindi nessuna selezione effettivamente avvenuta.

Come posso rilevare se l'utente ha effettivamente premuto qualcosa e non è una chiamata falsa da Android?

public class ListDittaListener implements OnNavigationListener{ 

    private BaseActivity activity; 

    private ListDittaListener() 
    { 

    } 

    public ListDittaListener(BaseActivity activity) 
    { 
     this.activity = activity; 
    } 

    @Override 
    public boolean onNavigationItemSelected(int itemPosition, long itemId) 
    { 
     MyApp appState = ((MyApp)this.activity.getApplicationContext()); 
     appState.setDittaSelezionata((int) itemId); 

     SharedPreferences settings = this.activity.getSharedPreferences(MyApp.PREFS_NAME, 0); 
     SharedPreferences.Editor editor = settings.edit(); 
     editor.putInt("ditta_id_selezionata", (int) itemId); 

      ////////restart activity this.activity.recreate(); 

     return false; 
    } 

} 

risposta

16

si può facilmente ignorare la prima chiamata a onNavigationItemSelected se ti piace:

public class Whatever implements OnNavigationListener { 
    private boolean synthetic = true; 

    @Override 
    public boolean onNavigationItemSelected(int itemPosition, long itemId) { 
     if (synthetic) { 
      synthetic = false; 
      return true; 
     } 

     // do whatever you really wanted here 
    } 
} 
+1

grazie ma come ho scritto nella descrizione di taglie, "mi piacerebbe evitare di usare un contatore e ignorare la prima chiamata ", questo sembra più un trucco, mi piacerebbe capire perché questo succede in primo luogo – max4ever

+3

Ho lo stesso problema ed è terribilmente fastidioso di hackerarlo in questo modo. C'è uno scopo per un simile comportamento? –

+0

Ho usato questa soluzione per evitare che i Frammenti vengano ricreati inutilmente due volte quando l'orientamento dello schermo cambia e perde il loro stato. Vedi [qui] (http://stackoverflow.com/a/14295474/963396). –

0

Bene Non riesco a vedere nulla di sbagliato nel codice corrente.

Come hai creato i tuoi elementi a discesa. E quale elemento è "seleziona" per Android dopo che la vista è stata creata. E cosa stai facendo nel tuo metodo onCreate in cui l'ActionBar viene inizializzato.

ho fatto come indicato qui e ha funzionato per me: http://developer.android.com/guide/topics/ui/actionbar.html#Dropdown

+0

"seleziona" il primo elemento dell'elemento a discesa, onCreate di solito richiama il codice dall'altra domanda collegata (fondamentalmente solo action_bar.setNavigationMode e action_bar.setListNavigationCallbacks) – max4ever

+0

Mhh sul punto di vista si sta facendo tutto corretto. Stai ruotando lo schermo? Ho trovato un problema simile qui: http: // StackOverflow.it/questions/9039045/how-to-set-active-item-in-the-action-bar-drop-down-navigation – Moritz

+0

no schermo rotante – max4ever

2

il sistema Android chiamerà onNavigationItemSelected (0, 0) dopo l'impostazione dell'attività. (Il che significa più tardi di onResume()).

Come altri ragazzi hanno menzionato, è meglio non fare alcun trucco come ignorare la prima chiamata, altrimenti il ​​sistema Android non richiamerà nuovamente NavigationItemSelected() quando si seleziona il primo indice. (Il sistema pensava che il primo elemento fosse già selezionato)

La mia soluzione è chiamare actionbar.setSelectedNavigationItem (il vero elemento # che si desidera) dopo aver configurato la barra di azione. Quindi il sistema chiamerà onNavigationItemSelected() due volte. Prima onNavigationItemSelected (0, 0) e poi onNavigationItemSelected (l'elemento reale #).

+0

Inizialmente hai detto, è meglio non ignorare la prima chiamata, ma cosa fai quando viene chiamato 'onNavigationItemSelected (0, 0)'? – skywall

0

ho viewpager con frammenti e ho bisogno di impostare barra di azione personalizzato per ogni frammento in pager Nella pagina desiderata ho lista di navigazione, gli incendi frammento onNavigationItemSelected automaticamente quando swipe pagine, voglio evitare questo comportamento e eseguire le attività solo se io voce di navigazione selezionata manualmente.

public class MyFragment extends Fragment implements ActionBar.OnNavigationListener { 

    private boolead fireReady = false; 

    @Override 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
     super.setUserVisibleHint(isVisibleToUser); 

     // every time make it false, this method invoked on swipe action 
     fireReady = false; 

     if (isVisibleToUser) { 
      // setup actionbar, you also can setup action bar in activity 
      String[] array = getActivity().getResources().getStringArray(R.array.users_order); 
      ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, array); 
      adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 

      getActivity().getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 
      getActivity().getActionBar().setListNavigationCallbacks(adapter, this); 
     } 

    } 

    @Override 
    public boolean onNavigationItemSelected(int itemPosition, long itemId) { 

     if (fireReady) { 
      // task fire only when you directly press navigation item 
      UsersTask task = new UsersTask(getActivity()); 
      task.setTaskListener(this); 
      task.execute(usersUrls[itemPosition]); 
     } else { 
      // make it true first time when page displayed 
      fireReady = true; 
     } 
     return false; 
    } 

} 

} 
4

Metodo onNavigationItemSelected(int itemPosition, long itemId) sarà chiamato comunque dalla barra azione.

Quello che si potrebbe desiderare di fare è dire alla barra di azione che cosa deve passare al metodo itemPosition alla prima chiamata. (In altre parole, per dire a action bar quale elemento di navigazione deve essere impostato dopo che l'attività è stata creata). Ecco il codice:

mActionBarMenuSpinnerAdapter = ...; 
mActionBar = getActionBar(); 
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 
mActionBar.setListNavigationCallbacks(mActionBarMenuSpinnerAdapter, this); 
mActionBar.setSelectedNavigationItem(###your_default_navigation_item_here###); 

Dopo aver fatto questo si può risolvere il problema applicando cambiamenti nel onNavigationItemSelected(int itemPosition, long itemId) se solo itemPosition è diverso.

Problemi correlati