J'ai créé une application Android avec une Spinner
et une TextView
. Ma tâche consiste à afficher l'élément sélectionné dans la liste déroulante de Spinner dans TextView. J'ai implémenté Spinner dans la méthode onCreate
de sorte que lorsque j'exécute le programme, il affiche une valeur dans TextView
(avant de sélectionner un élément dans la liste déroulante).
Je souhaite afficher la valeur dans TextView uniquement après avoir sélectionné un élément dans la liste déroulante. Comment puis-je faire cela?
Voici mon code:
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<CharSequence> 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.
Donc, la première fois gérer cela avec une valeur Integer
Exemple: Prenez initialement 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);
}
}
Vous pouvez le faire avec une valeur booléenne et en vérifiant les positions actuelles et précédentes. Vois ici
Il suffit de mettre cette ligne avant de définir OnItemSelectedListener
spinner.setSelection(0,false)
À 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.
Cela a fonctionné pour moi
L'initialisation de Spinner dans Android est parfois problématique. Le problème ci-dessus a été résolu par ce motif.
Spinner.setAdapter();
Spinner.setSelected(false); // must
Spinner.setSelection(0,true); //must
Spinner.setonItemSelectedListener(this);
L'adaptateur de paramétrage doit être la première partie et onItemSelectedListener (ceci) sera le dernier lors de l'initialisation d'un compteur. Par le motif ci-dessus, mon OnItemSelected () n’est pas appelé lors de l’initialisation de spinner
haha ... J'ai la même question . Quand initViews () fait comme ça. La séquence est la clé, auditeur est le dernier. Bonne chance !
spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);
Ma solution:
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();
}
}
Vous pouvez le faire de cette manière:
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) {
}
});
Au début, je crée un auditeur et l’attribue à un rappel variable; alors je crée un deuxième auditeur anonyme et quand ceci est appelé pour la première fois, cela change le listener
Une solution simple similaire qui permet à plusieurs filateurs est de placer AdapterView dans une collection - dans la superclasse Activités - lors de la première exécution de onItemSelected (...). Vérifiez ensuite si AdapterView est dans la collection avant de l'exécuter. Cela active un ensemble de méthodes dans la super-classe et prend en charge plusieurs AdapterViews et par conséquent plusieurs spinners.
Superclasse ...
private Collection<AdapterView> AdapterViewCollection = new ArrayList<AdapterView>();
protected boolean firstTimeThrough(AdapterView parent) {
boolean firstTimeThrough = ! AdapterViewCollection.contains(parent);
if (firstTimeThrough) {
AdapterViewCollection.add(parent);
}
return firstTimeThrough;
}
Sous-classe ...
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.
}
Essaye ça
spinner.postDelayed(new Runnable() {
@Override
public void run() {
addListeners();
}
}, 1000);.o
Vous pouvez y parvenir en définissant setOnTouchListener, puis setOnItemSelectedListener dans onTouch.
@Override
public boolean onTouch(final View view, final MotionEvent event) {
view.setOnItemSelectedListener(this)
return false;
}
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 les 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) {
userSelect = false;
// Your selection handling code here
}
}
}
Ajoutez l'auditeur au cinéaste en tant que OnItemSelectedListener
et OnTouchListener
:
SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
Pour éviter d'appeler spinner.setOnItemSelectedListener () pendant l'initialisation
spinner.setSelection(Adapter.NO_SELECTION, true); //Add this line before setting listener
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Avait le même problème et cela fonctionne pour moi:
J'ai 2 disques et je les mets à jour pendant l'init et pendant les interactions avec d'autres contrôles ou après avoir récupéré les données du serveur.
Voici mon modèle:
public class MyClass extends <Activity/Fragment/Whatever> 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) {
}
}
Lorsque la classe lance l'initialisation, utilisez setSpinnersListeners () au lieu de définir directement l'écouteur.
Le Runnable empêchera la roulette de tirer surItemSelected juste après que vous ayez défini leurs valeurs.
Si vous devez mettre à jour le compteur (après un appel au serveur, etc.), utilisez removeSpinnersListeners () juste avant vos lignes de mise à jour et setSpinnersListeners () juste après les lignes de mise à jour. Cela empêchera le déclenchement de onItemSelected après la mise à jour.
créer un champ booléen
private boolean inispinner;
à l'intérieur de l'activité
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (!inispinner) {
inispinner = true;
return;
}
//do your work here
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});