Android Spinner:在初始化期间避免onItemSelected调用

Gra*_*ant 134 android android-layout android-spinner

我用a Spinner和a 创建了Android应用程序TextView.我的任务是在TextView的Spinner下拉列表中显示所选项目.我在onCreate方法中实现了Spinner,所以当我运行程序时,它会显示一个值TextView(在从下拉列表中选择一个项目之前).

我只想在从下拉列表中选择一个项目后才在TextView中显示该值.我该怎么做呢?

这是我的代码:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class GPACal01Activity extends Activity implements OnItemSelectedListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Spinner spinner = (Spinner) findViewById(R.id.noOfSubjects);

        // Create an ArrayAdapter using the string array and a default spinner layout
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.noofsubjects_array, android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(this);
    }

    public void onItemSelected(AdapterView<?> parent, View arg1, int pos,long id) {
        TextView textView = (TextView) findViewById(R.id.textView1);
        String str = (String) parent.getItemAtPosition(pos);
        textView.setText(str);
    }

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

    }
}
Run Code Online (Sandbox Code Playgroud)

Abh*_*bhi 162

spinner.setOnItemSelectedListener(this); // Will call onItemSelected() Listener.
Run Code Online (Sandbox Code Playgroud)

所以第一次用任何Integer值处理它

示例:最初采取 int check = 0;

public void onItemSelected(AdapterView<?> parent, View arg1, int pos,long id) {
   if(++check > 1) {
      TextView textView = (TextView) findViewById(R.id.textView1);
      String str = (String) parent.getItemAtPosition(pos);
      textView.setText(str);
   }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用布尔值以及检查当前位置和先前位置来执行此操作.看这里

  • 它是一个补丁,我猜不是解决方案。 (6认同)
  • 真棒男人..当我第一次遇到这个问题时,我尝试实现自定义微调器..但它没有工作..但你的解决方案就像一个魅力......谢谢. (2认同)

Day*_*are 85

只需在设置OnItemSelectedListener之前放置此行

spinner.setSelection(0,false)
Run Code Online (Sandbox Code Playgroud)

  • 这是有效的,因为您首先设置选择,然后添加一个侦听器,但不会调用侦听器,因为您之前已经选择了此选择.只有新选择才会调用侦听器. (12认同)
  • 这不适用于Android API 23 (7认同)
  • 如果你想写这有用的原因和原因,那将是一个更好的答案. (6认同)
  • 这是因为`setSelection(int,boolean)`在内部调用`setSelectionInt()`,你需要在调用它之后设置监听器(而不是之前).请注意`setSelection(int)`将不起作用,因为它在内部调用`setNextSelectedPositionInt()`,这就是我在这里的原因. (3认同)
  • 如果在onCreateView()期间或之前声明它,则不起作用.将调用onItemSelected. (2认同)

Bil*_*ote 58

从API级别3开始,您可以在具有布尔值的Activity上使用onUserInteraction()来确定用户是否正在与设备进行交互.

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

@Override
public void onUserInteraction() {
     super.onUserInteraction();
     userIsInteracting = true;
}
Run Code Online (Sandbox Code Playgroud)

作为活动的一个领域,我有:

 private boolean userIsInteracting;
Run Code Online (Sandbox Code Playgroud)

最后,我的微调器:

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

           }
      });
Run Code Online (Sandbox Code Playgroud)

当你来完成活动时,布尔值会重置为false.奇迹般有效.

  • 这对于嵌套片段不起作用,因为onUserInteraction是Activity方法.还有其他方法吗? (4认同)
  • 好一个比尔......我认为这是一个比接受答案更好的解决方案 (3认同)

sak*_*ham 17

这对我有用

Spinner在Android中的初始化是有问题的,有时上述问题通过这种模式解决了.

Spinner.setAdapter();
Spinner.setSelected(false);  // must
Spinner.setSelection(0,true);  //must
Spinner.setonItemSelectedListener(this);
Run Code Online (Sandbox Code Playgroud)

设置适配器应该是第一部分,onItemSelectedListener(this)在初始化微调器时将是最后一个.通过上面的模式,在初始化微调器期间不会调用我的OnItemSelected()


Ket*_*ani 11

避免在初始化期间调用 spinner.setOnItemSelectedListener()

spinner.setSelection(Adapter.NO_SELECTION, true); //Add this line before setting listener
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    }

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

    }
});
Run Code Online (Sandbox Code Playgroud)


小智 10

哈哈......我有同样的问题.当initViews()只是这样做时.序列是关键,监听器是最后一个.祝好运 !

spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,以相同的方式使用spinner.setSelection(position,false).使用setSelection(position)方法,在初始化期间调用侦听器. (10认同)
  • @HugoGresse尝试调用spinner.setSelection(0,false); .事情是,现在它会忽略这个位置的选择,因为它已经被选中了 (2认同)

cod*_*eee 7

我的解决方案

protected boolean inhibit_spinner = true;


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

            if (inhibit_spinner) {
                inhibit_spinner = false;
            }else {

            if (getDataTask != null) getDataTask.cancel(true);
            updateData();
            }

        }
Run Code Online (Sandbox Code Playgroud)


Cha*_*ton 6

你可以通过这种方式做到这一点:

AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            //set the text of TextView
        }

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

        }
    });

yourSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            yourSpinner.setOnItemSelectedListener(listener);
        }

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

        }
    });
Run Code Online (Sandbox Code Playgroud)

首先,我创建一个监听器并归因于一个变量回调; 然后我创建第二个匿名监听器,当第一次调用它时,这会改变监听器=]


Ran*_*mar 5

然后,可以在 onTouch 方法中将用户交互标志设置为 true,并在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) { 
            userSelect = false;
            // Your selection handling code here
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

将侦听器添加到微调器中,同时作为 anOnItemSelectedListener和 an OnTouchListener

SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
Run Code Online (Sandbox Code Playgroud)