Android Spinner: Evite las llamadas OnItemSelected durante la inicialización

TextView una aplicación de Android con un Spinner y un TextView . Mi tarea es mostrar el elemento seleccionado de la lista desplegable del Girador en el TextView. Implementé Spinner en el método onCreate así que cuando estoy ejecutando el progtwig, muestra un valor en TextView (antes de seleccionar un elemento de la lista desplegable).

Quiero mostrar el valor en el TextView solo después de seleccionar un elemento de la lista desplegable. ¿Cómo hago esto?

Aquí está mi código:

 import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.TextView; public class GPACal01Activity extends Activity implements OnItemSelectedListener { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Spinner spinner = (Spinner) findViewById(R.id.noOfSubjects); // Create an ArrayAdapter using the string array and a default spinner layout ArrayAdapter adapter = ArrayAdapter.createFromResource(this,R.array.noofsubjects_array, android.R.layout.simple_spinner_item); // Specify the layout to use when the list of choices appears adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Apply the adapter to the spinner spinner.setAdapter(adapter); spinner.setOnItemSelectedListener(this); } public void onItemSelected(AdapterView parent, View arg1, int pos,long id) { TextView textView = (TextView) findViewById(R.id.textView1); String str = (String) parent.getItemAtPosition(pos); textView.setText(str); } public void onNothingSelected(AdapterView arg0) { // TODO Auto-generated method stub } } 

 spinner.setOnItemSelectedListener(this); // Will call onItemSelected() Listener. 

Así que la primera vez maneja esto con cualquier valor entero

Ejemplo: Inicialmente Take int check = 0;

 public void onItemSelected(AdapterView parent, View arg1, int pos,long id) { if(++check > 1) { TextView textView = (TextView) findViewById(R.id.textView1); String str = (String) parent.getItemAtPosition(pos); textView.setText(str); } } 

Puede hacerlo con valor booleano y también verificando las posiciones actual y anterior. Mira aquí

Simplemente ponga esta línea antes de establecer OnItemSelectedListener

 spinner.setSelection(0,false) 

A partir del nivel 3 de la API, puede usar onUserInteraction () en una actividad con un booleano para determinar si el usuario está interactuando con el dispositivo.

http://developer.android.com/reference/android/app/Activity.html#onUserInteraction ()

 @Override public void onUserInteraction() { super.onUserInteraction(); userIsInteracting = true; } 

Como un campo en la actividad que tengo:

  private boolean userIsInteracting; 

Finalmente, mi spinner:

  mSpinnerView.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView arg0, View view, int position, long arg3) { spinnerAdapter.setmPreviousSelectedIndex(position); if (userIsInteracting) { updateGUI(); } } @Override public void onNothingSelected(AdapterView arg0) { } }); 

A medida que avanza y avanza en la actividad, boolean se restablece a falso. Funciona de maravilla.

Esto funcionó para mí

La inicialización de Spinner en Android es problemática, algunas veces el problema anterior fue resuelto por este patrón.

 Spinner.setAdapter(); Spinner.setSelected(false); // must Spinner.setSelection(0,true); //must Spinner.setonItemSelectedListener(this); 

El adaptador de configuración debe ser la primera parte y onItemSelectedListener (esto) será el último al inicializar un spinner. Según el patrón anterior, mi OnItemSelected () no se llama durante la inicialización de spinner

jaja … tengo la misma pregunta. Cuando initViews () solo hace esto. La secuencia es la clave, el oyente es el último. Buena suerte !

 spinner.setAdapter(adapter); spinner.setSelection(position); spinner.setOnItemSelectedListener(listener); 

Mi solución:

 protected boolean inhibit_spinner = true; @Override public void onItemSelected(AdapterView arg0, View arg1, int pos, long arg3) { if (inhibit_spinner) { inhibit_spinner = false; }else { if (getDataTask != null) getDataTask.cancel(true); updateData(); } } 

Puedes hacer esto de esta manera:

 AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView adapterView, View view, int i, long l) { //set the text of TextView } @Override public void onNothingSelected(AdapterView adapterView) { } }); yourSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView adapterView, View view, int i, long l) { yourSpinner.setOnItemSelectedListener(listener); } @Override public void onNothingSelected(AdapterView adapterView) { } }); 

Al principio creo un oyente y lo atribuyo a una callback variable; entonces creo un segundo oyente anónimo y cuando esto se llama por primera vez, esto cambia el oyente =]

Una solución similar simple que permite múltiples spinners es poner el AdapterView en una colección, en la superclase Activities, en la primera ejecución de onItemSelected (…) Luego, verifique si el AdapterView está en la colección antes de ejecutarlo. Esto permite un conjunto de métodos en la superclase y es compatible con múltiples AdapterViews y, por lo tanto, múltiples spinners.

Superclase …

 private Collection AdapterViewCollection = new ArrayList(); protected boolean firstTimeThrough(AdapterView parent) { boolean firstTimeThrough = ! AdapterViewCollection.contains(parent); if (firstTimeThrough) { AdapterViewCollection.add(parent); } return firstTimeThrough; } 

Subclase …

 public void onItemSelected(AdapterView parent, View view, int pos, long id) { if (! firstTimeThrough(parent)) { String value = safeString(parent.getItemAtPosition(pos).toString()); String extraMessage = EXTRA_MESSAGE; Intent sharedPreferencesDisplayIntent = new Intent(SharedPreferencesSelectionActivity.this,SharedPreferencesDisplayActivity.class); sharedPreferencesDisplayIntent.putExtra(extraMessage,value); startActivity(sharedPreferencesDisplayIntent); } // don't execute the above code if its the first time through // do to onItemSelected being called during view initialization. 

}

Tenía el mismo problema y esto funciona para mí:

Tengo 2 hilanderos y los actualizo durante el inicio y durante las interacciones con otros controles o después de obtener datos del servidor.

Aquí está mi plantilla:

 public class MyClass extends  implements Spinner.OnItemSelectedListener { private void removeSpinnersListeners() { spn1.setOnItemSelectedListener(null); spn2.setOnItemSelectedListener(null); } private void setSpinnersListeners() { new Handler().postDelayed(new Runnable() { @Override public void run() { spn1.setOnItemSelectedListener(MyClass.this); spn2.setOnItemSelectedListener(MyClass.this); } }, 1); } @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { // Your code here } @Override public void onNothingSelected(AdapterView parent) { } } 

Cuando la clase está iniciando use setSpinnersListeners () en lugar de configurar directamente el oyente.

Runnable evitará que el spinner se active onItemSelected inmediatamente después de que establezca sus valores.

Si necesita actualizar la ruleta (después de una llamada al servidor, etc.) use removeSpinnersListeners () justo antes de sus líneas de actualización, y setSpinnersListeners () justo después de las líneas de actualización. Esto evitará que onItemSelected se active después de la actualización.

El indicador de interacción del usuario puede establecerse en verdadero en el método onTouch y reiniciarse en onItemSelected() una vez que se haya manejado el cambio de selección. Prefiero esta solución porque la bandera de interacción del usuario se maneja exclusivamente para el spinner, y no para otras vistas en la actividad que pueden afectar el comportamiento deseado.

En codigo:

Crea tu oyente para el spinner:

 public class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener { boolean userSelect = false; @Override public boolean onTouch(View v, MotionEvent event) { userSelect = true; return false; } @Override public void onItemSelected(AdapterView parent, View view, int pos, long id) { if (userSelect) { userSelect = false; // Your selection handling code here } } } 

Agregue el oyente al spinner como OnItemSelectedListener y OnTouchListener :

 SpinnerInteractionListener listener = new SpinnerInteractionListener(); mSpinnerView.setOnTouchListener(listener); mSpinnerView.setOnItemSelectedListener(listener); 

Usted podría lograrlo mediante setOnTouchListener primero y luego configureOnItemSelectedListener en onTouch

 @Override public boolean onTouch(final View view, final MotionEvent event) { view.setOnItemSelectedListener(this) return false; }