2010-09-03 9 views
6

Sembra che la classe Spinner di Android (e probabilmente ListView in generale, anche se non ne sono sicuro) chiama il metodo onItemSelected() di OnItemSelectedListener dopo aver chiamato setAdapter(), anche se l'utente non ha ancora selezionato esplicitamente qualcosa.Come evitare di avere spinner android chiamata itemselectedlistener quando si imposta l'adattatore?

Posso vedere come questo sarebbe utile in molte situazioni, ma ci sono momenti in cui voglio solo chiamare onItemSelected() quando un oggetto è effettivamente selezionato.

C'è un modo per controllare questo comportamento e hanno Spinner non chiama onItemSelected() dopo aver impostato l'adattatore?

risposta

4

Non ho usato questa soluzione per molto tempo ancora, quindi non sono del tutto sicuro che funziona come previsto, ma ho avuto fortuna finora con questa soluzione:

spinner.setOnItemSelectedListener(new OnItemSelectedListener() { 
     protected Adapter initializedAdapter = null; 

     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 

      // Always ignore the initial selection performed after setAdapter 
      if(initializedAdapter !=parent.getAdapter()) { 
       initializedAdapter = parent.getAdapter(); 
       return; 
      } 

      ... 
     } 
    } 

C'è un modo migliore?

+2

Se l'utente preme il primo elemento del il codice sopra non ha alcun effetto. – matheuslf

+0

Stesso problema che sto affrontando – theLazyFinder

0

Ho utilizzato i metodi setTag e getTag e ho creato un resource id chiamato "spinnerstate".

Quindi ogni volta che imposto l'adattatore al livello di programmazione, imposto il tag "spinnerstate" su "init" e, nell'evento infornato, lo imposta su "ready" e ignoro l'evento. (Si noti il ​​mio codice è Mono per Android SE EN avrà un aspetto diverso):

Set Adapter:

profileSpn.SetTag (Resource.Id.spinnerstate, "init"); 
profileSpn.Adapter = new ArrayAdapter (this, Android.Resource.Layout.SimpleSpinnerItem, items.ToArray()); 

Articolo evento selezionato:

string state = (string)((Spinner)sender).GetTag (Resource.Id.spinnerstate); 
    if (state == "init") { 
     ((Spinner)sender).SetTag (Resource.Id.spinnerstate, "ready"); 
     return; 
    } 

sono d'accordo che questo non è desiderato comportamento in quasi Il 100% dei casi, e non penso che sia un buon design da parte di Google, ma ci sei.

2

Aggiungi ascoltatore Spinner come di seguito:

spinner.post(new Runnable(){ 
    public void run() 
    { 
     spinner.setOnItemSelectedListener(new OnItemSelectedListener() { 

      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 

       ... 
      } 
     } 
    } 
}); 
0

ho fatto cose simili prima, ho usato valore di conteggio. L'utilizzo dell'oggetto adattatore padre è incompleto perché può essere un problema quando la vista viene aggiornata o getView() chiamato di nuovo.

Pertanto, vi consiglio usando array di contatore.

Inizialmente, definire la matrice di conteggio nell'adattatore globalmente.

private int isInitializedView[]; 

E quindi inizializzarlo su getView().

isInitializedView[position] = 0; 

Nell'ascoltatore di selezione, fare qualcosa che si desidera se è già inizializzato.

holder.mySpinner.setOnItemSelectedListener(new OnItemSelectedListener() { 
     @Override 
     public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) { 
      isInitializedView[position]++; 
      if(isInitializedView[position] > 1) { 
       // do someting that you want 
      } 
     } 

     @Override 
     public void onNothingSelected(AdapterView<?> parentView) {} 
    }); 

(Si noti che isInitializedView[position]++; possono essere venuto dopo if() di routine, e unico evento grilletto quando questo valore è >0. A voi la scelta.)

0

Ho avuto tre filatore nella mia attività e tutti i dati adattatore filatore ha stato riempito in fase di runtime (dai dati del servizio Web dopo la chiamata dal metodo onCreate).Quindi chiama automaticamente il metodo onItemSelected(AdapterView<?> parent, View view, int position, long id) di spinner. Ho risolto questo problema utilizzando il metodo onUserInteraction() di attività verificando questo metodo che l'utente sta interagendo con lo spinner o meno. Se sì allora eseguire l'azione altro non

  1. Dichiarare isUserIntract variabile booleana globale

  2. in uso onItemSelected metodo seguente procedura

    Se (isUserIntract) {

    // eseguire Azione

    } else {

    // non eseguire l'azione

    }

  3. uso sottostante Codice nell'attività

@Override

public void onUserInteraction() { 
super.onUserInteraction(); 
isUserIntract = true; 
} 
Problemi correlati