Spinner onItemSelected () se ejecuta incorrectamente

Posible duplicado:
Android Spinner OnItemSelected fue llamado Erroneously (sin acción del usuario al abrir el spinner)

¿Alguien sabe cómo evitar que se ejecute el método onItemSelected () (interfaz OnItemSelectedListener) cuando se crea una instancia del diseño? Necesito saber si hay una manera de hacer esto porque quiero mantener la instancia de mi diseño separado de este oyente.

Intenté crear una instrucción if inicialmente configurada en falso alrededor de todo el código dentro del método reemplazado, pero no hay forma de saber cuándo establecerlo en verdadero porque el método reemplazado se ejecuta después de onCreate (), onStart () y métodos onResume () cada vez.

No he encontrado ninguna respuesta clara sobre esto. Cualquier solución clara sería muy apreciada.

David, aquí hay un tutorial que escribí para este problema …

Planteamiento del problema

un onItemSelected () indeseable se activa mientras se está inicializando Gallery (o Spinner). Esto significa que el código se ejecuta prematuramente; código que se pretende ejecutar ÚNICAMENTE cuando un usuario hace una selección físicamente.

Solución

  1. en onCreate (), cuente cuántos widgets de Galería (o Spinner) tiene en la vista. (mGalleryCount)
  2. en onItemSelected (), cuente con qué frecuencia se ha activado. (mGalleryInitializedCount)
  3. when (mGalleryInitializedCount

Ejemplo de código

public class myActivity extends Activity implements OnItemSelectedListener { //this counts how many Gallery's are on the UI private int mGalleryCount=0; //this counts how many Gallery's have been initialized private int mGalleryInitializedCount=0; //UI reference private Gallery mGallery; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myxmllayout); //get references to UI components mGallery = (Gallery) findViewById(R.id.mygallery); //trap selection events from gallery mGallery.setOnItemSelectedListener(this); //trap only selection when no flinging is taking place mGallery.setCallbackDuringFling(false); // //do other stuff like load images, setAdapter(), etc // //define how many Gallery's are in this view //note: this could be counted dynamically if you are programmatically creating the view mGalleryCount=1; } public void onItemSelected(AdapterView parent, View view, int position, long id) { if (mGalleryInitializedCount < mGalleryCount) { mGalleryInitializedCount++; } else { //only detect selection events that are not done whilst initializing Log.i(TAG, "selected item position = " + String.valueOf(position) ); } } } 

Por qué esto funciona

esta solución funciona porque la Galería finaliza la inicialización mucho antes de que un usuario pueda realizar una selección.

Aquí hay una versión modificada del código “Someone Somewhere”. Puede usarlo si tiene una sola vista.

 public class myActivity extends Activity implements OnItemSelectedListener { // Set view initialization to false while the it is being built private boolean initializedView = false; //UI reference private Gallery mGallery; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myxmllayout); //get references to UI components mGallery = (Gallery) findViewById(R.id.mygallery); //trap selection events from gallery mGallery.setOnItemSelectedListener(this); //trap only selection when no flinging is taking place mGallery.setCallbackDuringFling(false); // //do other stuff like load images, setAdapter(), etc // } public void onItemSelected(AdapterView parent, View view, int position, long id) { if (initializedView == false) { initializedView = true; } else { //only detect selection events that are not done whilst initializing Log.i(TAG, "selected item position = " + String.valueOf(position) ); } } } 

La misma solución:

 private int m_intSpinnerInitiCount = 0; private static final int NO_OF_EVENTS = 1; ... m_spnTemplates.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parentView, View selectedItemView, int position, long id) { //trying to avoid undesired spinner selection changed event, a known problem if (m_intSpinnerInitiCount < NO_OF_EVENTS) { m_intSpinnerInitiCount++; } else { //YOUR CODE HERE } } 

Ayer encontré este problema con un OnCheckedChangedListener. Terminé agregando una variable de instancia booleana inicializada a verdadera dentro de mi clase de adaptador con un método de acceso isListenerEnabled (). Luego establecí la variable en falso en mi código de diseño y lo configuré en verdadero al final del código de diseño. En mi oyente, inspecciono el valor de la variable para decidir si ejecutar el código del oyente o no.

Puede volver a establecer su variable en false cada vez que se onPause . En cuanto a cuándo establecerlo en true , puede hacer esto para el primer evento de movimiento / tecla / trackball después de onResume .

También busqué una buena solución en Internet pero no encontré ninguna que satisficiera mis necesidades. Así que escribí esta extensión en la clase Spinner para que pueda establecer un OnItemClickListener simple, que tiene el mismo comportamiento que un ListView.

Solo cuando un elemento se ‘selecciona’, se llama al onItemClickListener.

¡Diviértete con eso!

 public class MySpinner extends Spinner { private OnItemClickListener onItemClickListener; public MySpinner(Context context) { super(context); } public MySpinner(Context context, AttributeSet attrs) { super(context, attrs); } public MySpinner(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void setOnItemClickListener(android.widget.AdapterView.OnItemClickListener inOnItemClickListener) { this.onItemClickListener = inOnItemClickListener; } @Override public void onClick(DialogInterface dialog, int which) { super.onClick(dialog, which); if (this.onItemClickListener != null) { this.onItemClickListener.onItemClick(this, this.getSelectedView(), which, this.getSelectedItemId()); } } }