2010-09-03 4 views
6

Wygląda na to, że klasa Spinner Androida (i prawdopodobnie ogólnie ListView, chociaż nie wiem na pewno) wywołuje metodę OnItemSelectedListener onItemSelected() po wywołaniu setAdapter(), nawet jeśli użytkownik jeszcze niczego nie wybrał jawnie.Jak uniknąć sytuacji, w której android spinner wywołuje itemselectedlistener przy ustawianiu adaptera?

Widzę, jak przydałoby się to w wielu sytuacjach, ale zdarzają się sytuacje, gdy chcę tylko zadzwonić pod numer onItemSelected(), gdy przedmiot jest rzeczywiście wybrany.

Czy istnieje sposób kontrolowania tego zachowania i czy Spinner NIE zadzwoni pod numer onItemSelected() po ustawieniu adaptera?

Odpowiedz

4

I nie korzystał z tego rozwiązania jeszcze bardzo długo, więc nie jestem całkowicie przekonany, że działa zgodnie z oczekiwaniami, ale miałem szczęście do tej pory z tego rozwiązania:

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; 
      } 

      ... 
     } 
    } 

Czy istnieje lepszy sposób?

+2

Jeśli użytkownik nacisnął na pierwszą pozycję powyższy kod nie ma żadnego efektu. – matheuslf

+0

Ten sam problem mam do czynienia – theLazyFinder

0

Użyłem metod setTag i getTag i utworzyłem resource id o nazwie "spinnerstate".

Następnie za każdym razem, gdy programowo ustawiam adapter, ustawiam tag "spinnerstate" na "init", aw wypalonym zdarzeniu ustaw go na "gotowy" i zignoruj ​​zdarzenie. (Uwaga mój kod jest Mono dla Androida se będzie to wyglądać inaczej):

Set Adapter:

profileSpn.SetTag (Resource.Id.spinnerstate, "init"); 
profileSpn.Adapter = new ArrayAdapter (this, Android.Resource.Layout.SimpleSpinnerItem, items.ToArray()); 

przedmiotu wybranego zdarzenia:

string state = (string)((Spinner)sender).GetTag (Resource.Id.spinnerstate); 
    if (state == "init") { 
     ((Spinner)sender).SetTag (Resource.Id.spinnerstate, "ready"); 
     return; 
    } 

Zgadzam się, że to nie jest pożądane zachowanie w prawie 100% przypadków, ale nie sądzę, że to dobry projekt ze strony Google, ale proszę bardzo.

2

Dodaj słuchacza obrotowemu jak poniżej:

spinner.post(new Runnable(){ 
    public void run() 
    { 
     spinner.setOnItemSelectedListener(new OnItemSelectedListener() { 

      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 

       ... 
      } 
     } 
    } 
}); 
0

robiłem podobne rzeczy wcześniej, użyłem wartość licznika. Korzystanie z obiektu adaptera nadrzędnego jest niekompletne, ponieważ może to być problem, gdy widok jest odświeżany lub ponownie wywoływana jest getView().

Dlatego polecam używanie tablicy liczników.

Najpierw zdefiniuj tablicę liczników w adapterze globalnie.

private int isInitializedView[]; 

A następnie zainicjować go na getView().

isInitializedView[position] = 0; 

W selektorze wyboru, zrób coś, co chcesz, jeśli zostało już zainicjowane.

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) {} 
    }); 

(Zauważ, że isInitializedView[position]++; można przyjść po if() rutyny, a jedynie zdarzenie wyzwalania, gdy wartość ta jest >0. To Twój wybór.)

0

miałem trzy pokrętła w mojej działalności, a wszystkie dane adapter tarczy ma zostały wypełnione w czasie wykonywania (z danych usługi internetowej po wywołaniu z metody onCreate).Dlatego automatycznie wywołuje metodę spinnera. Rozwiązałem ten problem, używając metody onUserInteraction() metody działania sprawdź tę metodę, z którą użytkownik korzysta z pokrętła lub nie. jeśli tak to wykonać akcję innego nie

  1. stwierdzenie isUserIntract logiczną zmienną globalnie

  2. w użyciu onItemSelected metody zgodnie z procedurą

    Jeśli (isUserIntract) {

    // wykonać Działanie

    } else {

    // nie wykonywać działania

    }

  3. skorzystać z poniższego kodu aktywności

@Override

public void onUserInteraction() { 
super.onUserInteraction(); 
isUserIntract = true; 
} 
Powiązane problemy