Spinner onItemSelected называется ошибочно (без действий пользователя)

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

Ответ 2

Другой вариант в духе решения Билла Мота - сделать OnItemSelectedListener также OnTouchListener. Флаг взаимодействия с пользователем может быть установлен в значение true в методе onTouch и reset в onItemSelected() после изменения выбора. Я предпочитаю это решение, потому что флаг взаимодействия с пользователем обрабатывается исключительно для счетчика, а не для других видов активности, которые могут повлиять на желаемое поведение.

В коде:

Создайте свой слушатель для счетчика:

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

}

Добавьте слушателя к счетчику как как OnItemSelectedListener, так и OnTouchListener:

SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);

Ответ 3

Вы можете просто добавить число int для его решения:)

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

Ответ 4

Начиная с уровня API 3, вы можете использовать onUserInteraction() для Activity с логическим значением, чтобы определить, взаимодействует ли пользователь с устройством.

http://developer.android.com/reference/android/app/Activity.html#onUserInteraction()

@Override
public void onUserInteraction() {
    super.onUserInteraction();
    userIsInteracting = true;
}

В качестве поля в Activity я:

private boolean userIsInteracting;

Наконец, мой счетчик:

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

        }
    });

Когда вы приходите и проходите через операцию, логическое значение reset равно false. Работает как шарм.

Ответ 5

Я решил эту проблему по-другому, так как иногда заметил, что метод onItemSelected вызывался дважды при изменении ориентации или иногда один раз.

Казалось, что это зависит от выбора текущего счетчика. Значит, для меня не работал флаг или счетчик. Вместо этого я записываю системное время в BOTH onResume() и onCreate, используя   widgetsRestartTime = System.currentTimeMillis()

widgetsRestartTime объявляется как double и как переменная intance.

Теперь в методе onItemSelected() я снова проверяю текущее время и вычитаю из него widgetsRestartTime следующим образом:   if (System.currentTimeMillis() - widgetsRestartTime > 200) {    // инициированное пользователем событие - так что это реальное событие spinner, поэтому обработайте его    } else {     // генерируемое системой событие, например. изменение ориентации, запуск активности. поэтому игнорировать    }

Ответ 6

Да, то, что вы видите, является правильным и является поведением по умолчанию, вы не можете это предотвратить. Вызов OnItemSelected обращается к начальной загрузке. После этой начальной загрузки он запускается только при каждом изменении пользователем выбора или при изменении выбора из вашего кода. У вас может быть индикатор, который может рассказать вам, было ли событие результатом начальной загрузки и проигнорировало первое событие, если вы не хотите его обрабатывать.

Ответ 7

У меня была та же проблема, и я решил ее, вспомнив предыдущее выбранное значение счетчика. При каждом вызове onItemSelected я сравниваю новое значение с предыдущим, и если он тот же, я не обрабатываю код дальше.

Ответ 8

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

Я нашел другое решение, хотя:

  • Установите TAG по умолчанию на spinner при его инициализации, в onCreate() вашей активности или onCreateView вашего фрагмента и перед установкой слушателя
  • В слушателе проверьте тег, если он присутствует, затем удалите его и не выполните код, вернувшись.

Что он, он работает как шарм!

Пример в слушателе:

        if(((String)parent.getTag()).equalsIgnoreCase(TAG_SPINNERVALUE))
        {
            parent.setTag("");
            return;
        }

P.S. И это работает для одного и того же слушателя, установленного на несколько прядильщиков!

Ответ 9

Если вы также покупаете первоначально не выбранный Spinner, вы можете пойти с

@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
    if(pos != 0) {
        pos--;

        // your code here
    }
}

Так как элемент 0 невозможно выбрать. Приветствия: -)

Ответ 10

Это сработало для меня,

private boolean isSpinnerInitial = true;

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

    if(isSpinnerInitial)
    {
        isSpinnerInitial = false;
    }
    else  {
        // do your work...
    }

}

Ответ 11

Я также искал хорошее решение в Интернете, но не нашел того, что удовлетворяло мои потребности. Поэтому я написал это расширение в классе Spinner, чтобы вы могли установить простой OnItemClickListener, который имеет то же поведение, что и ListView.

Только когда элемент получает "выбранный", вызывается onItemClickListener.

Получайте удовольствие от этого!

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

Ответ 12

Вы должны сделать это следующим образом. Последовательность - это ключ.

spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);

Ответ 13

Если вы не возражаете, используя позицию для promt, вы можете делать что-то подобное каждый раз, когда хотите, чтобы персонал работал на счетчике. Сначала установите выделение в прозвище:

spinner.setselected(0);
spinner.add("something");
...

И тогда сделайте что-нибудь подобное при выборе:

spinner.ItemSelected += (object sender, AdapterView.ItemSelectedEventArgs e) => 
            {
                if (spinner.SelectedItemPosition != 0)
                {
                   //do staff
                } 
            }

Ответ 14

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

spinner.setSelection(count, false);

Итак, поставьте это перед установкой OnItemSelectedListener:

spinner.setSelection(0,false);

Вы можете узнать больше на странице разработчиков:

https://developer.android.com/reference/android/widget/Spinner.html