Spinner Android: Ottenere l'evento di modifica elemento selezionato
-
20-09-2019 - |
Domanda
Come è possibile impostare il listener di eventi per uno Spinner quando la voce selezionata?
Fondamentalmente quello che sto cercando di fare è qualcosa di simile a questo:
spinner1.onSelectionChange = handleSelectionChange;
void handleSelectionChange(Object sender){
//handle event
}
Soluzione
Alcune delle risposte precedenti non sono corrette. Lavorano per altri widget e punti di vista, ma la documentazione per la widget di "noreferrer" Spinner afferma chiaramente:
Un filatore non supporta voce click eventi. La chiamata a questo metodo solleverà un'eccezione.
OnItemSelectedListener () invece:
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// your code here
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
Questo funziona per me.
Si noti che il metodo onItemSelected viene anche invocato quando la vista viene costruire, in modo da poter valutare l'ipotesi all'interno metodo onCreate()
chiamata.
Altri suggerimenti
Spinner spnLocale = (Spinner)findViewById(R.id.spnLocale);
spnLocale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
// Your code here
}
public void onNothingSelected(AdapterView<?> adapterView) {
return;
}
});
Nota: Ricordate una cosa.
evento Spinner OnItemSelectedListener
verrà eseguita due volte:
- inizializzazione Spinner
- l'utente selezionato manualmente
Prova a differenziare quei due variabili utilizzando bandiera.
È possibile implementare classe AdapterView.OnItemSelectedListener
nella vostra attività.
E poi utilizzare la linea in basso all'interno onCreate()
Spinner spin = (Spinner) findViewById(R.id.spinner);
spin.setOnItemSelectedListener(this);
Poi ignorare questi due metodi:
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
selection.setText(items[position]);
}
public void onNothingSelected(AdapterView<?> parent) {
selection.setText("");
}
https://stackoverflow.com/q/1714426/811625
È possibile evitare l'OnItemSelectedListener () viene chiamato con un semplice controllo:. Memorizzare l'indice selezione corrente in una variabile intera e controllare all'interno del onItemSelected (..) prima di fare qualsiasi
per esempio:
Spinner spnLocale;
spnLocale = (Spinner)findViewById(R.id.spnLocale);
int iCurrentSelection = spnLocale.getSelectedItemPosition();
spnLocale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (iCurrentSelection != i){
// Your code here
}
iCurrentSelection = i;
}
public void onNothingSelected(AdapterView<?> adapterView) {
return;
}
});
Di causa la iCurrentSelection
dovrebbe essere portata oggetto per questo al lavoro!
Trova il tuo nome filatore e trovare id quindi implementare questo metodo.
spinnername.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// your code here
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
La documentazione per il filatore-widget di dice
Un filatore non supporta gli eventi articolo scatti.
Si dovrebbe usare setOnItemSelectedListener
per gestire il problema.
Non importa vi impostare OnItemSelectedListener in onCreate o onStart - sarà ancora chiamato durante la creazione di attività o iniziare (rispettivamente)
.
Così siamo in grado di impostare in onCreate (e non in onStart!).
Basta aggiungere un flag di capire prima inizializzazione:
private Spinner mSpinner;
private boolean mSpinnerInitialized;
poi nel onCreate (o onCreateView) semplicemente:
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (!mSpinnerInitialized) {
mSpinnerInitialized = true;
return;
}
// do stuff
}
public void onNothingSelected(AdapterView<?> adapterView) {
return;
}
});
spinner1.setOnItemSelectedListener(
new AdapterView.OnItemSelectedListener() {
//add some code here
}
);
Se volete una vera onChangedListener (). Memorizzare il valore iniziale nel gestore e controllare per vedere se è cambiato. E 'semplice e fa non richiede una variabile globale. Funziona se si dispone di più di un filatore nella pagina.
String initialValue = // get from Database or your object
mySpinner.setOnItemSelectedListener(new SpinnerSelectedListener(initialValue));
...
protected class SpinnerSelectedListener implements AdapterView.OnItemSelectedListener {
private SpinnerSelectedListener() {
super();
}
public SpinnerSelectedListener(String initialValue) {
this();
this.initialValue = initialValue;
}
private String initialValue;
// getter and setter removed.
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
final String newValue = (String) spinHeight.getItemAtPosition(position);
if (newValue.equals(initialValue) == false) {
// Add your code here. The spinner has changed value.
// Maybe useful.
// initialValue = newValue;
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Maybe useful.
// initialValue = null;
}
}
Gli oggetti sono tuo amico, li usano.
spinner.setOnItemSelectedListener(
new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
//add some code here
}
);
prendere una variabile globale per la selezione corrente di filatore:
int currentItem = 0;
spinner_counter = (Spinner)findViewById(R.id.spinner_counter);
String[] value={"20","40","60","80","100","All"};
aa=new ArrayAdapter<String>(this,R.layout.spinner_item_profile,value);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_counter.setAdapter(aa);
spinner_counter.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(currentItem == position){
return; //do nothing
}
else
{
TextView spinner_item_text = (TextView) view;
//write your code here
}
currentItem = position;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
//R.layout.spinner_item_profile
<?xml version="1.0" encoding="utf-8"?>
<TextView android:id="@+id/spinner_item_text"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/border_close_profile"
android:gravity="start"
android:textColor="@color/black"
android:paddingLeft="5dip"
android:paddingStart="5dip"
android:paddingTop="12dip"
android:paddingBottom="12dip"
/>
//drawable/border_close_profile
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#e2e3d7" />
</shape>
</item>
<item android:left="1dp"
android:right="1dp"
android:top="1dp"
android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="@color/white_text" />
</shape>
</item>
</layer-list>
Questo funziona inizializzare il filatore e findViewById e utilizzare questo funzionerà
Spinner schemeStatusSpinner;
schemeStatusSpinner = (Spinner) dialog.findViewById(R.id.spinner);
schemeStatusSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// your code here
if(schemeStatusSpinner.getSelectedItemId()==4){
reasonll.setVisibility(View.VISIBLE);
}
else {
reasonll.setVisibility(View.GONE);
}
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
Il modo migliore quello che penso sarebbe quello di avere un flagitemselected = 0;
in onCreate()
. E sulla voce selezionata incremento caso in cui la bandiera cioè flagitemselected++
; e quindi controllare
if(flagitemselected!=1)
{
// do your work here
}
Questo aiuterà immagino.
Un trucco che ho trovato è stato mettere le setOnItemSelectedListeners in onWindowFocusChanged invece di onCreate. Non ho trovato alcun effetto collaterale male a farlo in questo modo, ancora. In sostanza, configurare gli ascoltatori dopo la finestra viene disegnato. Non sono sicuro di quanto spesso onWindowFocusChanged piste, ma è abbastanza facile da crea una variabile di blocco, se si stanno trovando in esecuzione troppo spesso.
Credo che Android potrebbe utilizzare un sistema di elaborazione basata su messaggi, e se si mette tutto in onCreate, si può incorrere in situazioni in cui l'ogiva viene popolato dopo che viene disegnato. Quindi, il listener sarà sparare dopo aver impostato la posizione dell'elemento. Si tratta di un'ipotesi, naturalmente, ma sentitevi liberi di correggere me su questo.