2010-09-03 12 views
6

Похоже, что класс Spinner для Android (и, возможно, ListView в целом, хотя я точно не знаю) вызывает ваш метод onItemSelected() OnItemSelectedListener после вызова setAdapter(), даже если пользователь еще явно ничего не выбрал.Как избежать установки элемента выбора звонка андроида при выборе адаптера?

Я вижу, как это было бы полезно во многих ситуациях, но бывают случаи, когда я хочу, чтобы onItemSelected() вызывался, когда элемент действительно выбран.

Есть ли способ контролировать это поведение, а Spinner NOT - позвонить onItemSelected() после установки адаптера?

ответ

4

Я не использовал это решение очень долго еще, так что я не совсем уверен, что это работает, как ожидалось, но я вез до сих пор с этим обходным путем:

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

      ... 
     } 
    } 

Есть лучший путь?

+2

Если пользователь нажал на первый элемент в код выше не действует. – matheuslf

+0

Тот же вопрос, с которым я сталкиваюсь – theLazyFinder

0

Я использовал методы setTag и getTag и создал resource id под названием «spinnerstate».

Тогда, когда я программно устанавливаю адаптер, я устанавливаю тег «spinnerstate» в «init», а в запущенном событии устанавливаем его в «ready» и игнорируем событие. (Обратите внимание на мой код Mono для Android зе он будет выглядеть по-другому):

Set Adapter:

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

Изделие выбрано событие:

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

Я согласен, что это не желательно поведение почти 100% случаев, и я не думаю, что это хороший дизайн со стороны Google, но там вы идете.

2

Добавить слушателя Spinner, как показано ниже:

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

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

       ... 
      } 
     } 
    } 
}); 
0

Я делал подобные вещи раньше, я использовал значение счетчика. Использование родительского объекта-адаптера является неполным, потому что это может быть проблемой при обновлении вида или getView().

Поэтому я рекомендую использовать массив счетчиков.

Сначала определите массив счетчиков в глобальном масштабе.

private int isInitializedView[]; 

И затем инициализируйте его на getView().

isInitializedView[position] = 0; 

В прослушивателе выбора сделайте то, что вы хотите, если оно уже инициализировано.

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

(Обратите внимание, что isInitializedView[position]++; можно прийти после if() рутины, и только инициирующего событие, когда это значение >0. Это ваш выбор.)

0

У меня был три блесны в моей деятельности, и все вертушка адаптер данные имеют были заполнены во время выполнения (из данных веб-сервиса после вызова из метода onCreate).Поэтому он автоматически вызывает метод onItemSelected(AdapterView<?> parent, View view, int position, long id). Я решил эту проблему, используя метод onUserInteraction() действия проверить этот метод, с которым пользователь взаимодействует со счетчиком или нет. если да, то выполнить действие еще не

  1. Объявить isUserIntract логическую переменную глобально

  2. в использовании onItemSelected метода следующая процедура

    Если (isUserIntract) {

    // выполнить Действие

    } еще {

    // не выполнять действия

    } использование

  3. ниже код активности

@Override

public void onUserInteraction() { 
super.onUserInteraction(); 
isUserIntract = true; 
}