Android Spinner:获取所选的项目更改事件

Son*_*Ali 385 events android spinner android-spinner

如何在所选项目更改时为Spinner设置事件侦听器?

基本上我想要做的是类似于这样的事情:

spinner1.onSelectionChange = handleSelectionChange;

void handleSelectionChange(Object sender){
    //handle event
}
Run Code Online (Sandbox Code Playgroud)

znq*_*znq 791

以前的一些答案是不正确的.它们适用于其他小部件和视图,但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
    }

});
Run Code Online (Sandbox Code Playgroud)

这适合我.

请注意,在构建视图时也会调用onItemSelected方法,因此您可以考虑将其放在onCreate()方法调用中.

  • 这个问题是在构建视图时也会调用onItemSelected方法.因此,在那里编写的代码也会在启动时执行.是否有一种方法只有在用户调用了真实项目选择时才执行包含代码? (42认同)
  • 实际上,可以通过将setOnItemSelectedListener放在重写OnStart方法而不是onCreate方法中来解决该问题.愚蠢的我... (38认同)
  • 我把监听器放在onStart方法中,但是在用户看到任何东西之前调用它,就像onCreate一样,所以,在我的情况下,一个"继续"按钮,在用户选择某个东西之前是不可见的,初始显示时,该按钮可见.你是说你的经历有所不同吗?如果是这样,你在onStart方法中做了哪些我不同的做法? (15认同)
  • 在匿名侦听器中使用另一个字段来记录第一个选择,并告诉onItemSelected不要做任何事情,除非遇到选择?只是一个想法. (7认同)
  • 但是,如果用户选择"默认"项目,顶部的那个项目怎么办?然后`onItemSelected(...)`没有被击中.(我知道,因为我刚刚发现了这个问题.) (4认同)
  • 我将一个类变量int设置为我将在onCreate中添加的微调器侦听器的数量,并在调用每个onItemSelected时递减它.直到它达到零,他们才回来. (2认同)

San*_*osh 54

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;
    } 
}); 
Run Code Online (Sandbox Code Playgroud)

注意:记住一件事.

Spinner OnItemSelectedListener事件将执行两次:

  1. Spinner初始化
  2. 用户手动选择

尝试使用flag变量来区分这两者.

  • 只需设置一个像布尔值一样的全局布尔值initialDisplay = true; 然后在你的onSelect中查看它是否为真,如果是,则不要做任何你在select上做的事情,而是将标志设置为false,以便下次调用它(当用户实际选择时). (17认同)
  • 我个人感到震惊的是,这么简单的东西 - 这样一个基本的UI小部件 - 实现起来很难实现......严重的是 - 构建一个'默认显示项'属性并将布尔标志属性构建到对象中有多难班级本身?我不是Objective C的粉丝,但我会说iOS小部件的实现大约是Android的1/10. (6认同)
  • 我也同意.Spinner是一个搞砸的小部件.很难知道弹出或关闭何时打开或关闭.要为此添加活动会难吗?上面的解决方案几乎可以告诉你列表何时打开或关闭但有三个问题:(1)没有选择已经选择的项目的事件(并且列表关闭)和(2)没有中止事件(触摸) off-list to close it)和(3)onNothingSelected似乎永远不会为我开火. (4认同)
  • 我也被召唤两次!我无法弄清楚你如何区分这两者? (3认同)

Dha*_*eem 17

您可以AdapterView.OnItemSelectedListener在Activity中实现类.

然后使用下面的内容 onCreate()

Spinner spin = (Spinner) findViewById(R.id.spinner);
spin.setOnItemSelectedListener(this);
Run Code Online (Sandbox Code Playgroud)

然后覆盖这两个方法:

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

public void onNothingSelected(AdapterView<?> parent) {
    selection.setText("");
}
Run Code Online (Sandbox Code Playgroud)


Sam*_*ath 16

/sf/ask/120009851/

您可以通过简单检查来避免调用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;
    } 
}); 
Run Code Online (Sandbox Code Playgroud)

因为iCurrentSelection应该在对象范围内工作!

  • 如果使用此@dahvyd是正确的,则int必须为final。无论如何,它确实运行良好。如果未选择位置0,并且禁用了它,则我将禁用EditText字段,然后重新启用它。谢谢你 (2认同)

dro*_*.me 8

找到您的微调名称并找到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
    }
});
Run Code Online (Sandbox Code Playgroud)


小智 7

spinner-widget的文档说:"一个微调器不支持项目点击事件." 您应该使用"setOnItemSelectedListener"来处理您的问题


Leo*_*der 7

您可以在onCreate或onStart中设置OnItemSelectedListener无关紧要-仍将在Activity创建或启动期间分别调用它。
因此我们可以在onCreate中设置它(而不是在onStart中!)。
只需添加一个标志就可以确定首次初始化:

private Spinner mSpinner;
private boolean mSpinnerInitialized;
Run Code Online (Sandbox Code Playgroud)

然后在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;
            }
        });
Run Code Online (Sandbox Code Playgroud)


Chi*_*han 5

spinner1.setOnItemSelectedListener(
    new AdapterView.OnItemSelectedListener() {
        //add some code here
    }
);
Run Code Online (Sandbox Code Playgroud)

  • 这并没有解决首次启动微调器时调用此回调的问题(从而引发与实际选择的项目无关的响应)。 (3认同)

Abd*_*fiz 5

对于 kotlin,您可以使用:

spinner.onItemSelectedListener =  object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        
    }

    override fun onNothingSelected(p0: AdapterView<*>?) {
        
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:对于onItemSelected方法的参数,我使用自定义变量名称