Ich habe einen Spinner, den ich in einer Dialogansicht zeige, und sobald der Dialog gestartet wird, wird onItemSelected
aufgerufen. Ich möchte das nicht wirklich verarbeiten, sondern nur, wenn der Benutzer die Auswahl trifft. Also muss ich dies entweder verhindern (vielleicht weil es keinen Standardwert gibt?) Oder ich muss wissen, dass nicht der Benutzer diese Auswahl vornimmt.
Androider, ich habe eine Lösung für dieses Problem gefunden und es hier gepostet (mit Codebeispiel):
Spinner onItemSelected () wird ausgeführt, wenn nicht angenommen wird, dass
Eine weitere Option im Sinne von Bill Motes Lösung besteht darin, aus der OnItemSelectedListener
auch eine OnTouchListener
zu machen. Das Benutzerinteraktionsflag kann dann in der onTouch-Methode auf true gesetzt und in onItemSelected()
zurückgesetzt werden, sobald die Auswahländerung behandelt wurde. Ich bevorzuge diese Lösung, weil das Benutzerinteraktionsflag ausschließlich für den Spinner und nicht für andere Ansichten in der Aktivität gehandhabt wird, die das gewünschte Verhalten beeinflussen können.
In Code:
Erstellen Sie Ihren Listener für den 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;
}
}
}
Fügen Sie dem Spinner den Listener als OnItemSelectedListener
und OnTouchListener
hinzu:
SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
Sie können einfach eine int-Anzahl hinzufügen, um sie zu lösen :)
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) {
}
});
Ab API Level 3 können Sie onUserInteraction () für eine Activity mit einem Boolean verwenden, um festzustellen, ob der Benutzer mit dem Gerät interagiert.
http://developer.Android.com/reference/Android/app/Activity.html#onUserInteraction ()
@Override
public void onUserInteraction() {
super.onUserInteraction();
userIsInteracting = true;
}
Als Feld auf der Aktivität habe ich:
private boolean userIsInteracting;
Zum Schluss mein 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) {
}
});
Wenn Sie kommen und die Aktivität durchlaufen, wird der Boolean auf false zurückgesetzt. Klappt wunderbar.
Ich habe dieses Problem auf eine andere Weise gelöst, da ich manchmal bemerkte, dass die Methode onItemSelected zweimal bei einer Orientierungsänderung oder manchmal einmal aufgerufen wurde.
Es schien von der aktuellen Auswahl der Spinner abzuhängen. Also funktionierte eine Flagge oder ein Schalter nicht für mich. Stattdessen zeichne ich die Systemzeit in BEIDE onResume () und onCreate mit WidgetsRestartTime = System.currentTimeMillis () auf.
widgetsRestartTime wird als double und als intance-Variable deklariert.
Jetzt prüfe ich in der onItemSelected () - Methode erneut die aktuelle Uhrzeit und subtrahiere widgetsRestartTime wie folgt: If (System.currentTimeMillis () - widgetsRestartTime> 200) { // Benutzer ausgelöstes Ereignis - Dies ist also ein echtes Spinnerereignis, so dass es } sonst { // verarbeitet wird Orientierungsänderung, Aktivitätsstart. ignoriere also }
Ich hatte das gleiche Problem. Die akzeptierte Lösung funktionierte jedoch nicht für mich, da ich mehrere Spinner in meinem Formular habe. Einige davon sind versteckt. Wenn die Spinner ausgeblendet sind, feuert der Zuhörer nicht. Daher ist das Zählen keine Lösung für mich.
Ich habe eine andere Lösung gefunden obwohl:
Das ist es, es funktioniert wie ein Zauber!
Beispiel im Listener:
if(((String)parent.getTag()).equalsIgnoreCase(TAG_SPINNERVALUE))
{
parent.setTag("");
return;
}
P.S. Und das funktioniert für den gleichen Listener, der auf mehrere Spinner eingestellt ist!
Ja, was Sie sehen, ist korrekt und ist das Standardverhalten. Sie können dies nicht verhindern. Der OnItemSelected-Callback wird beim ersten Laden aufgerufen. Nach diesem ersten Laden wird es nur ausgelöst, wenn der Benutzer die Auswahl ändert oder wenn Sie die Auswahl innerhalb Ihres Codes ändern. Sie können über ein Kennzeichen verfügen, das Sie darüber informiert, ob das Ereignis ein Ergebnis der Erstladung war, und das erste Ereignis ignorieren, wenn Sie es nicht verarbeiten möchten.
Ich hatte das gleiche Problem und löste es, indem ich mich an den zuvor ausgewählten Spinnerwert erinnerte. Bei jedem Aufruf von onItemSelected vergleiche ich den neuen Wert mit dem vorherigen, und wenn er identisch ist, verarbeite ich den Code nicht weiter.
Wenn Sie auch einen zunächst nicht ausgewählten Spinner kaufen, können Sie mit gehen
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if(pos != 0) {
pos--;
// your code here
}
}
Da Artikel 0 niemals ausgewählt werden kann. Prost :-)
Es hat für mich funktioniert,
private boolean isSpinnerInitial = true;
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
if(isSpinnerInitial)
{
isSpinnerInitial = false;
}
else {
// do your work...
}
}
Sie sollten es so machen. Die Reihenfolge ist der Schlüssel.
spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);
Ich habe auch im Internet nach einer guten Lösung gesucht, aber keine gefunden, die meine Bedürfnisse befriedigt. Ich habe diese Erweiterung in der Spinner-Klasse geschrieben, sodass Sie einen einfachen OnItemClickListener festlegen können, der das gleiche Verhalten aufweist als ListView.
Nur wenn ein Element ausgewählt wird, wird der onItemClickListener aufgerufen.
Viel Spass damit!
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());
}
}
}
Wenn es Ihnen nichts ausmacht, eine Position für Promt zu verwenden, können Sie dies jedes Mal tun, wenn Sie Mitarbeiter am Spinner sind. Erste Auswahl auf das Promt setzen:
spinner.setselected(0);
spinner.add("something");
...
Und dann machen Sie so etwas, wenn die Auswahl geschieht:
spinner.ItemSelected += (object sender, AdapterView.ItemSelectedEventArgs e) =>
{
if (spinner.SelectedItemPosition != 0)
{
//do staff
}
}
Sie können versuchen, den Spinner mit zwei Argumenten wie folgt einzustellen:
spinner.setSelection(count, false);
Setzen Sie das also vor den OnItemSelectedListener:
spinner.setSelection(0,false);
Sie können mehr auf der Entwicklerseite überprüfen:
https://developer.Android.com/reference/Android/widget/Spinner.html