Как избежать того, чтобы Android Spinner вызывал itemselectedlistener при настройке адаптера? - PullRequest
6 голосов
/ 03 сентября 2010

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

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

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

Ответы [ 5 ]

4 голосов
/ 03 сентября 2010

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

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

            ...
        }
    }

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

3 голосов
/ 02 марта 2014

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

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

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

                ...
            }
        }
    }
});
0 голосов
/ 11 августа 2015

В моей деятельности было три счетчика, и все данные адаптера счетчика были заполнены во время выполнения (из данных веб-службы после вызова из метода 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;
}
0 голосов
/ 06 апреля 2014

Я делал подобные вещи раньше, я использовал значение счетчика.Использование родительского объекта адаптера является неполным, потому что это может быть проблемой при обновлении представления или повторном вызове 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 голосов
/ 06 марта 2013

Я использовал методы setTag и getTag и создал идентификатор ресурса , называемый "spinnerstate".

Затем, когда я программно устанавливаю адаптер, яустановите для тэга «spinnerstate» значение «init», а в событии «Fired» установите для него значение «ready» и проигнорируйте событие.(обратите внимание, мой код Mono для Android выглядит иначе):

Установить адаптер:

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, но все готово.

...