Come evitare di avere chiamata filatore Android onitemselectedlistener quando si imposta adattatore?
-
30-09-2019 - |
Domanda
Sembra classe Spinner che di Android (e possibilmente ListView in generale, anche se non so per certo) chiama il metodo onItemSelected()
di OnItemSelectedListener dopo aver chiamato setAdapter()
, anche se l'utente non ha selezionato in modo esplicito ancora nulla.
Posso vedere come questo sarebbe utile in molte situazioni, ma ci sono momenti in cui voglio solo onItemSelected()
da chiamare quando un elemento è in realtà specificamente selezionati.
C'è un modo per controllare questo comportamento e hanno Spinner non chiama onItemSelected()
dopo aver impostato l'adattatore?
Soluzione
Non ho molto tempo ancora, quindi non sono del tutto sicuro che funziona come previsto utilizzato questa soluzione per, 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?
Altri suggerimenti
Aggiungi ascoltatore a filatore 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) {
...
}
}
}
});
Ho usato il setTag e getTag metodi, e ha creato una risorsa id chiama "spinnerstate".
Poi ogni volta che a livello di codice impostare la scheda, ho impostato il tag "spinnerstate" a "init", e in caso sparato, impostarlo su "pronto" e ignorare l'evento. (Si noti il ??mio codice è Mono per Android se si 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 credo che sia un buon design da parte di Google, ma ci si va.
ho fatto cose simili prima, ho usato valore di conteggio. Utilizzando oggetto adattatore genitore è incompleta perché può essere un problema quando schermo sia aggiornato o getView()
chiamò di nuovo.
Pertanto, vi consiglio usando array di contatore.
Inizialmente, definire array di conteggio adattatore globalmente.
private int isInitializedView[];
E poi inizializzare su GetView ().
isInitializedView[position] = 0;
Nel listener 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 può essere isInitializedView[position]++;
verranno dopo di routine if()
, e unico evento grilletto quando questo valore è >0
. A voi la scelta.)
Ho avuto tre filatore nella mia attività e tutti i dati Adattatore ogiva è stata riempita in fase di esecuzione (da dati web-service dopo la chiamata dal metodo onCreate
). Quindi chiamare automaticamente il metodo onItemSelected(AdapterView<?> parent, View view, int position, long id)
di filatore.
Ho risolto questo problema utilizzando onUserInteraction () metodo di attività
controllare questo metodo l'utente interagisce con ogiva oppure no. Se sì allora eseguire l'azione altro non
-
Declare isUserIntract variabile booleana a livello mondiale
-
a utilizzare il metodo
onItemSelected
seguente proceduraSe (isUserIntract) {
// eseguire Azione
} else {
// non eseguire l'azione
}
-
utilizzo qui di seguito il codice di attività
@Override
public void onUserInteraction() {
super.onUserInteraction();
isUserIntract = true;
}