Je montre une boîte de dialogue que je montre dans une vue de dialogue, et le moment où la boîte de dialogue commence onItemSelected
est appelée. Je ne veux pas vraiment traiter cela, mais seulement quand l'utilisateur choisit. Donc je dois soit empêcher cela (peut-être parce qu'aucune valeur par défaut n'est définie?), Ou j'ai besoin de savoir que ce n'est pas l'utilisateur qui fait cette sélection?
Androider, j'ai trouvé une solution à ce problème et l'a posté ici (avec un exemple de code):
Spinner onItemSelected () s'exécute quand ce n'est pas supposé
Une autre option dans l'esprit de la solution de Bill Mote est de faire de OnItemSelectedListener
également un OnTouchListener
. L'indicateur d'interaction utilisateur peut ensuite être défini sur true dans la méthode onTouch et réinitialisé dans onItemSelected()
une fois que le changement de sélection a été traité. Je préfère cette solution car l'indicateur d'interaction utilisateur est traité exclusivement pour le cinéaste, et non pour d'autres vues de l'activité pouvant affecter le comportement souhaité.
Dans du code:
Créez votre auditeur pour le 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) {
// Your selection handling code here
userSelect = false;
}
}
}
Ajoutez l'auditeur au cinéaste en tant que OnItemSelectedListener
et OnTouchListener
:
SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
Vous pouvez simplement ajouter un compte int pour le résoudre :)
sp.setOnItemSelectedListener(new OnItemSelectedListener() {
int count=0;
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
if(count >= 1){
int item = sp.getSelectedItemPosition();
Toast.makeText(getBaseContext(),
"You have selected the book: " + androidBooks[item],
Toast.LENGTH_SHORT).show();
}
count++;
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
À partir du niveau 3 de l'API, vous pouvez utiliser onUserInteraction () sur une activité avec un booléen pour déterminer si l'utilisateur interagit avec le périphérique.
http://developer.Android.com/reference/Android/app/Activity.html#onUserInteraction ()
@Override
public void onUserInteraction() {
super.onUserInteraction();
userIsInteracting = true;
}
En tant que champ de l'activité, j'ai:
private boolean userIsInteracting;
Enfin, mon 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) {
}
});
Au fur et à mesure que vous avancez dans l'activité, le booléen est remis à faux. Fonctionne comme un charme.
J'ai résolu ce problème d'une manière différente car j'ai remarqué que parfois la méthode onItemSelected était appelée deux fois lors du changement d'orientation ou parfois une fois.
Cela semblait dépendre de la sélection actuelle des disques. Donc, un drapeau ou un comptoir ne fonctionnait pas pour moi. Au lieu de cela, j’enregistre l’heure du système dans BOTH onResume () et onCreate en utilisant widgetsRestartTime = System.currentTimeMillis ()
widgetsRestartTime est déclaré en tant que double et variable intance.
Maintenant, dans la méthode onItemSelected (), je vérifie à nouveau l'heure actuelle et en soustrais widgetsRestartTime comme suit: if (System.currentTimeMillis () - widgetsRestartTime> 200) { // événement déclenché par l'utilisateur - il s'agit donc d'un véritable événement spinner. Traitez-le donc } autre { // événement généré par le système, par exemple. changement d'orientation, démarrage d'activité. alors ignore }
J'ai eu le même problème. Mais la solution acceptée n'a pas fonctionné pour moi car j'ai plusieurs disques sur ma fiche, dont certains sont cachés. Lorsque les disques sont masqués, l'auditeur ne se déclenche pas. Compter n'est donc pas une solution pour moi.
J'ai trouvé une autre solution quoique:
Ca y est, ça marche à merveille!
Exemple dans l'auditeur:
if(((String)parent.getTag()).equalsIgnoreCase(TAG_SPINNERVALUE))
{
parent.setTag("");
return;
}
P.S. Et cela fonctionne pour le même auditeur réglé sur plusieurs fileurs!
Oui, ce que vous voyez est correct et correspond au comportement par défaut. Vous ne pouvez pas empêcher cela. Le rappel OnItemSelected est appelé lors du chargement initial. Après ce chargement initial, il est uniquement déclenché chaque fois que l'utilisateur modifie la sélection ou si vous modifiez la sélection dans votre code. Vous pouvez avoir un indicateur qui peut vous indiquer si l'événement est le résultat du chargement initial et ignorer le premier événement si vous ne souhaitez pas le traiter.
J'ai eu le même problème, et je l'ai résolu en gardant à l'esprit la valeur précédemment sélectionnée pour la casserole. Sur chaque appel onItemSelected, je compare la nouvelle valeur à la précédente et, si elle est identique, je ne traite plus le code.
Si vous achetez également un initialement non sélectionné Spinner , vous pouvez aller avec
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if(pos != 0) {
pos--;
// your code here
}
}
Depuis l'élément 0 n'est jamais possible de sélectionner. À votre santé :-)
Cela a fonctionné pour moi
private boolean isSpinnerInitial = true;
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
if(isSpinnerInitial)
{
isSpinnerInitial = false;
}
else {
// do your work...
}
}
Vous devriez faire comme ceci. La séquence est la clé.
spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);
J'ai aussi cherché une bonne solution sur Internet mais n'en ai trouvé aucune qui réponde à mes besoins ... J'ai donc écrit cette extension sur la classe Spinner afin que vous puissiez définir un simple OnItemClickListener ListView.
OnItemClickListener est appelé uniquement lorsqu'un élément est "sélectionné".
Aie du plaisir avec ça!
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());
}
}
}
Si cela ne vous dérange pas d’utiliser un poste de promt, vous pouvez le faire chaque fois que vous souhaitez recruter du personnel sur la roulette. Première sélection du promt:
spinner.setselected(0);
spinner.add("something");
...
Et puis faites quelque chose comme ça quand la sélection se produit:
spinner.ItemSelected += (object sender, AdapterView.ItemSelectedEventArgs e) =>
{
if (spinner.SelectedItemPosition != 0)
{
//do staff
}
}
Vous pouvez essayer de définir le compteur en utilisant deux arguments, comme ceci:
spinner.setSelection(count, false);
Donc, mettez ceci avant l'ensemble OnItemSelectedListener:
spinner.setSelection(0,false);
Vous pouvez en savoir plus sur la page des développeurs:
https://developer.Android.com/reference/Android/widget/Spinner.html