Как избежать наличия Android Spinner Call EstateSelistener при настройке адаптера?
-
30-09-2019 - |
Вопрос
Похоже, что класс спиннера Android (и, возможно, ListView в целом, хотя я не знаю наверняка), называет ваш OniteSeSelistener onItemSelected()
Метод после вызова setAdapter()
, Даже если пользователь еще ничего не выбрал.
Я вижу, как это будет полезно во многих ситуациях, но есть времена, когда я только хочу только onItemSelected()
быть вызванным, когда элемент на самом деле выбран специально.
Есть ли способ контролировать это поведение и иметь спиннер не звонить onItemSelected()
После установки адаптера?
Решение
Я еще не использовал это решение в течение очень давно, поэтому я не уверен, что это работает как ожидалось, но мне повезло, но мне повезло с этим обходным путем:
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;
}
...
}
}
Есть ли способ лучше?
Другие советы
Добавьте слушатель в Spinner, как ниже:
spinner.post(new Runnable(){
public void run()
{
spinner.setOnItemSelectedListener( new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
...
}
}
}
});
Я использовал рассеивание и методы GetTag, и создал Идентификатор ресурса под названием «Spinnerstate».
Затем, когда я программно устанавливаю адаптер, я установил тег «Spinnerstate» в «init», а в спущенном событии установите его на «Ready» и игнорируйте событие. (Примечание мой код моно для Android SE будет выглядеть по-другому):
Установить адаптер:
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, но там вы идете.
Я сделал подобные вещи раньше, я использовал значение Count. Использование объекта родительского адаптера является неполным, потому что это может быть проблемой при обновлении просмотра или 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
Отказ Это твой выбор.)
У меня было три спиннер в моей деятельности, и все данные адаптера спиннер были заполнены во время выполнения (из данных веб-службы после звонка из onCreate
метод). Так что он автоматически звонит onItemSelected(AdapterView<?> parent, View view, int position, long id)
Способ спиннера. Я решил эту проблему, используя OnUserInteraction () Метод деятельности Проверьте этот метод, который пользователь взаимодействует со спиннером или нет. Если да, то выполните действие еще не
Объявлять IsuserIntract. логическая переменная глобально
в
onItemSelected
Способ использовать следующую процедуруЕсли (IsuserIntract) {
// выполнить действие
} еще{
// не выполнять действие
}
Используйте ниже код в деятельности
@Override.
public void onUserInteraction() {
super.onUserInteraction();
isUserIntract = true;
}