Cómo evitar tener llamada spinner androide onitemselectedlistener al configurar el adaptador?
-
30-09-2019 - |
Pregunta
Parece clase Spinner de que Android (y posiblemente ListView en general, aunque no sé a ciencia cierta), se llamará al método onItemSelected()
de OnItemSelectedListener después de llamar setAdapter()
, incluso si el usuario no ha seleccionado explícitamente nada todavía.
Puedo ver cómo esto podría ser útil en muchas situaciones, pero hay momentos en los que sólo quieren onItemSelected()
que se llamará cuando un elemento se selecciona realmente específicamente.
¿Hay una manera de controlar este comportamiento y tiene Spinner no llama a onItemSelected()
después de configurar el adaptador?
Solución
No he utilizado esta solución por mucho tiempo todavía, así que no estoy totalmente seguro de que funciona como se esperaba, pero he tenido suerte hasta ahora con esta solución:
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;
}
...
}
}
¿Hay una mejor manera?
Otros consejos
Añadir oyente a Spinner, como a continuación:
spinner.post(new Runnable(){
public void run()
{
spinner.setOnItemSelectedListener( new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
...
}
}
}
});
He utilizado el setTag y GetTag métodos, y crearon una href="http://developer.android.com/guide/topics/resources/more-resources.html#Id" rel="nofollow"> recursos llama "spinnerstate".
A continuación, cada vez que me puse el adaptador de programación, me puse la etiqueta "spinnerstate" a "init", y en el caso despedido, otra vez en "listo" e ignorar el evento. (Tenga en cuenta mi código es Mono para Android sí que tendrá un aspecto diferente):
Conjunto adaptador:
profileSpn.SetTag (Resource.Id.spinnerstate, "init");
profileSpn.Adapter = new ArrayAdapter (this, Android.Resource.Layout.SimpleSpinnerItem, items.ToArray ());
Artículo evento seleccionado:
string state = (string)((Spinner)sender).GetTag (Resource.Id.spinnerstate);
if (state == "init") {
((Spinner)sender).SetTag (Resource.Id.spinnerstate, "ready");
return;
}
Estoy de acuerdo que esto no se desea el comportamiento en casi el 100% de los casos, y no creo que sea un buen diseño por parte de Google, pero hay que ir.
Hice cosas similares antes, que utilizan el valor de conteo. Utilizando el objeto adaptador de matriz es incompleta, ya que puede ser un problema cuando la vista se actualiza o getView()
llamó de nuevo.
Por lo tanto, recomiendo que el uso conjunto de contador.
En primer lugar, definir gama de recuento en el adaptador a nivel mundial.
private int isInitializedView[];
Y entonces inicializar en getView ().
isInitializedView[position] = 0;
En el oyente selección, hacer algo que desea si ya se ha inicializado.
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) {}
});
(Tenga en cuenta que isInitializedView[position]++;
puede venir después de la rutina if()
, y sólo evento de disparo cuando este valor es >0
. Es su elección.)
Yo tenía tres spinner en mi actividad y todos los datos adaptador de ruleta se ha llenado en tiempo de ejecución (a partir de datos de servicios web después de la llamada de método onCreate
). Por lo tanto, llamar automáticamente onItemSelected(AdapterView<?> parent, View view, int position, long id)
método de ruleta.
He resuelto este problema mediante el uso de onUserInteraction () método de actividad
comprobar este método que el usuario está interactuando con spinner o no. Si sí, entonces realizan la acción demás no
-
Declare isUserIntract variable booleana globalmente
-
en
onItemSelected
el uso del método siguiente procedimientoSi (isUserIntract) {
// realizar la acción
} else {
// no realizar la acción
}
-
uso por debajo de código en la actividad
@ Override
public void onUserInteraction() {
super.onUserInteraction();
isUserIntract = true;
}