Android Spinner: получить событие изменения выбранного элемента

Как вы можете установить прослушиватель событий для Spinner, когда выбранный элемент изменяется?

По сути, я пытаюсь сделать что-то похожее на это:

spinner1.onSelectionChange = handleSelectionChange;

void handleSelectionChange(Object sender){
    //handle event
}
370
задан Vadim Kotov 26 July 2019 в 10:38
поделиться

14 ответов

Некоторые из предыдущих ответов не верны. Они работают для других виджетов и представлений, но документация для виджета Spinner четко гласит:

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

Лучше использовать OnItemSelectedListener () вместо:

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
        // your code here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        // your code here
    }

});

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

Обратите внимание, что метод onItemSelected также вызывается во время построения представления, поэтому вы можете рассмотреть возможность помещения его в вызов метода onCreate().

763
ответ дан Shine 26 July 2019 в 10:38
поделиться
  • 1
    Я имею дело с CQRS с точки зрения ASP.NET MVC (к лучшему или к худшему), и мои контроллеры, которые создают и выдают команды, действительно просто выполняют минимальное количество действий. Проверка ввода, отправленного клиентом, чтобы определить, следует ли вводить команду или нет, и подготовка представления. Моя бизнес-логика содержится в моем домене и не проникает в пользовательский интерфейс. Я думаю, что вы движетесь в правильном направлении здесь. Удачи! – David Hoerster 7 March 2011 в 12:20

Это будет работать, инициализируя спиннер и findviewbyid, и использовать это будет работать

    Spinner schemeStatusSpinner;

  schemeStatusSpinner = (Spinner) dialog.findViewById(R.id.spinner);

schemeStatusSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
            // your code here
            if(schemeStatusSpinner.getSelectedItemId()==4){
                reasonll.setVisibility(View.VISIBLE);
            }
            else {
                reasonll.setVisibility(View.GONE);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parentView) {
            // your code here
        }

    });
1
ответ дан sanjay 26 July 2019 в 10:38
поделиться
  • 1
    @ Тудор: Знаете ли вы, что британский комедийный очерк, где разница между "может" и "может" объясняется? Одна из релевантных цитат из этого была бы: "Вы Can, но вы May нет." (Ссылка не идет на эскиз, потому что я больше не могу ее найти.: -) – stakx 19 June 2014 в 23:07

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

int currentItem = 0;

spinner_counter = (Spinner)findViewById(R.id.spinner_counter);
String[] value={"20","40","60","80","100","All"};
aa=new ArrayAdapter<String>(this,R.layout.spinner_item_profile,value);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_counter.setAdapter(aa);

spinner_counter.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if(currentItem == position){
                return; //do nothing
            }
            else
            {
                 TextView spinner_item_text = (TextView) view;
                 //write your code here
            }
            currentItem = position;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

//R.layout.spinner_item_profile
<?xml version="1.0" encoding="utf-8"?>

<TextView  android:id="@+id/spinner_item_text"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" 
android:layout_height="wrap_content"
android:background="@drawable/border_close_profile"
android:gravity="start"  
android:textColor="@color/black"         
android:paddingLeft="5dip"
android:paddingStart="5dip"
android:paddingTop="12dip"
android:paddingBottom="12dip"
/>

//drawable/border_close_profile
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
   <shape android:shape="rectangle">
    <solid android:color="#e2e3d7" />
   </shape>
 </item>
<item android:left="1dp"
android:right="1dp"
android:top="1dp"
android:bottom="1dp">
<shape android:shape="rectangle">
    <solid android:color="@color/white_text" />
</shape>
</item>
</layer-list>
3
ответ дан indrajeet 26 July 2019 в 10:38
поделиться
  • 1
    @stakx :) Да & quot; может & quot; это лучшее слово для описания того, что пользователю следует разрешить делать. – Tudor 20 June 2014 в 07:52

Один трюк, который я нашел, заключался в размещении ваших setOnItemSelectedListeners в onWindowFocusChanged вместо onCreate. Я не нашел никаких побочных эффектов, если бы сделал это таким образом. По сути, настройте слушателей после того, как окно будет нарисовано. Я не уверен, как часто запускается onWindowFocusChanged, но достаточно легко создать себе переменную блокировки, если вы обнаружите, что она работает слишком часто.

Я думаю, что Android может использовать систему обработки сообщений, и если вы поместите все это в onCreate, вы можете столкнуться с ситуациями, когда счетчик заполняется после его отрисовки. Таким образом, ваш слушатель отключится после того, как вы установите местоположение элемента. Конечно, это обоснованное предположение, но не стесняйтесь меня поправлять.

0
ответ дан Joe Plante 26 July 2019 в 10:38
поделиться
  • 1
    Но я думаю, что вы все равно хотите, чтобы CanDoX запрашивал , чтобы затемнить некоторые команды в пользовательском интерфейсе. – Josh Kodroff 9 February 2012 в 15:46

Лучший способ, как мне кажется, это иметь flagitemselected = 0; в onCreate(). И на выбранном элементе события увеличивают этот флаг, т. Е. flagitemselected++; а затем проверьте

if(flagitemselected!=1)
{
// do your work here
}

Это поможет, я думаю.

1
ответ дан ppreetikaa 26 July 2019 в 10:38
поделиться
  • 1
    CanDoX может использоваться сервисом авторизации / слоем, созданным специально для стороны запроса. CanDoX звучит как проверка авторизации для просмотра чего-либо. CanDoX == IsAuthorizedToDoX (CanViewX / IsAuthorizedToViewX). Большая часть CanDoX командной стороны должна быть разработана в самой модели. Может ли пользователь быть автором? Может ли книга быть изменена автором, это часть вездесущего языка – Tudor 19 June 2014 в 21:33

Найдите имя вашего счетчика и найдите id, затем реализуйте этот метод.

spinnername.setOnItemSelectedListener(new OnItemSelectedListener() {

    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
        // your code here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        // your code here
    }
});
7
ответ дан dakshbhatt21 26 July 2019 в 10:38
поделиться
  • 1
    Випин Саху. Да, я пробовал обе эти вещи. То есть Сброс adb, с помощью любого из трех методов, которые я перечислил. Проверка того, что эмулятор или устройство распознаны (в представлении eclipse DDMS > панель «Устройства»: посмотрите перечисленные эмулятор или устройство. Или из командной строки «adb devices»). Затем установка .apk через eclipse или командную строку; на эмулятор или физическое устройство. – John Bentley 20 June 2012 в 09:27
spinner.setOnItemSelectedListener(
            new AdapterView.OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> arg0, View arg1,
                        int arg2, long arg3) {

                    // TODO Auto-generated method stub
                }

                @Override
                public void onNothingSelected(AdapterView<?> arg0) {
                    // TODO Auto-generated method stub

                }
                //add some code here
            }
        );
3
ответ дан kaub0st3r 26 July 2019 в 10:38
поделиться
  • 1
    спасибо за ответ и подтверждение понимания, к которому я пришел. То, что я не понял в начале, было то, что есть разница между проверкой команды по текущему состоянию домена и проверкой самой команды . Я полностью упустил последний момент и подумал, что оба они - одно и то же и происходят в области; теперь мне ясно, что только первый шаг проверки происходит в домене; и только последнее когда-либо отражается в пользовательском интерфейсе такими средствами, как отключенные кнопки команд и т. д. – stakx 11 March 2011 в 08:57

Неважно, будете ли вы устанавливать OnItemSelectedListener в onCreate или onStart - он будет по-прежнему вызываться во время создания или запуска Activity (соответственно).
Таким образом, мы можем установить его в onCreate (а НЕ в onStart!).
Просто добавьте флаг, чтобы определить первую инициализацию:

private Spinner mSpinner;
private boolean mSpinnerInitialized;

, затем в onCreate (или onCreateView), просто:

mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                if (!mSpinnerInitialized) {
                    mSpinnerInitialized = true;
                    return;
                }

                // do stuff
            }

            public void onNothingSelected(AdapterView<?> adapterView) {
                return;
            }
        });
5
ответ дан Leo Droidcoder 26 July 2019 в 10:38
поделиться
  • 1
    Я хотел бы услышать, как обратная связь возвращается клиенту (за исключением истории по электронной почте). – Alex Burtsev 19 April 2012 в 21:36

В документах для виджета «Spinner» указано

«Spinner» не поддерживает события щелчка элемента.

Вы должны использовать setOnItemSelectedListener для решения вашей проблемы.

7
ответ дан Ronin 26 July 2019 в 10:38
поделиться
  • 1
    попробуйте adb kill-server, затем adb start-server, затем adb install имя пакета ... если это не работает в эмуляторе, то вы сказали, что у вас есть рутированное устройство, попробуйте то же самое в нем ... – Vipin Sahu 20 June 2012 в 09:17

Если вы хотите истинный onChangedListener (). Сохраните начальное значение в обработчике и проверьте, изменилось ли оно. Он прост и не требует глобальной переменной. Работает, если у вас есть более одного счетчика на странице.

String initialValue = // get from Database or your object
mySpinner.setOnItemSelectedListener(new SpinnerSelectedListener(initialValue));

...

protected class SpinnerSelectedListener implements AdapterView.OnItemSelectedListener {

        private SpinnerSelectedListener() {
            super();
        }

        public SpinnerSelectedListener(String initialValue) {
            this();
            this.initialValue = initialValue;
        }

        private String initialValue;

        // getter and setter removed.  

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            final String newValue = (String) spinHeight.getItemAtPosition(position);
            if (newValue.equals(initialValue) == false) {
               // Add your code here.  The spinner has changed value. 

               // Maybe useful.   
               // initialValue = newValue;
            }

        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
               // Maybe useful.   
               // initialValue = null; 
        }
    }

Объекты - ваш друг, используйте их.

4
ответ дан fishjd 26 July 2019 в 10:38
поделиться
  • 1
    Вы пропустили, что я написал выше "Увеличено время ожидания соединения ADB. Затмение > Окно > Настройки > Android > DDMS > & Quot; Время ожидания соединения ADB (мс): & quot; = 10000 (я тоже пробовал 60000). & Quot; – John Bentley 20 June 2012 в 08:59

https://stackoverflow.com/q/1714426/811625

Вы можете избежать вызова OnItemSelectedListener () с помощью простой проверки: сохранить текущий индекс выбора в целое число переменной и проверьте в onItemSelected (..), прежде чем делать что-либо.

Например:

Spinner spnLocale;

spnLocale = (Spinner)findViewById(R.id.spnLocale);

int iCurrentSelection = spnLocale.getSelectedItemPosition();

spnLocale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { 
    if (iCurrentSelection != i){
            // Your code here
    }
    iCurrentSelection = i;
    } 

    public void onNothingSelected(AdapterView<?> adapterView) {
        return;
    } 
}); 

Потому что iCurrentSelection должен находиться в области действия объекта, чтобы это работало!

15
ответ дан Community 26 July 2019 в 10:38
поделиться
  • 1
    Отключение даже не нужно, переключения флага должно быть достаточно. – Giulio Piancastelli 26 August 2012 в 19:32
spinner1.setOnItemSelectedListener(
    new AdapterView.OnItemSelectedListener() {
        //add some code here
    }
);
5
ответ дан Guido 26 July 2019 в 10:38
поделиться

Вы можете реализовать класс AdapterView.OnItemSelectedListener в своей деятельности.

А затем используйте следующую строку в пределах onCreate()

Spinner spin = (Spinner) findViewById(R.id.spinner);
spin.setOnItemSelectedListener(this);

Затем переопределите эти два метода:

public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
    selection.setText(items[position]);
}

public void onNothingSelected(AdapterView<?> parent) {
    selection.setText("");
}
17
ответ дан dakshbhatt21 26 July 2019 в 10:38
поделиться
  • 1
    Работал для меня - отключил, переключил, включил и сразу же работал - как глупо – Simon 28 September 2012 в 10:35
Spinner spnLocale = (Spinner)findViewById(R.id.spnLocale);

spnLocale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { 
        // Your code here
    } 

    public void onNothingSelected(AdapterView<?> adapterView) {
        return;
    } 
}); 

Примечание: Помните одну вещь.

Событие Spinner OnItemSelectedListener будет выполнено дважды:

  1. Инициализация Spinner
  2. Пользователь выбран вручную

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

51
ответ дан Vasily Kabunov 26 July 2019 в 10:38
поделиться
  • 1
    Спасибо за добавление возможного решения, которое я не упомянул. Я попробовал это (не задумываясь). К счастью, я решил эту проблему, обновив компьютер до Windows 8. – John Bentley 10 February 2013 в 02:36
Другие вопросы по тегам:

Похожие вопросы: