我有一个spinner,在对话框视图中显示,当对话框启动时,onItemSelected
被调用。我不想在这个时候处理它,只想在用户进行选择时处理。所以我要么需要阻止这种情况发生(也许因为没有设置默认值?),要么我需要知道不是用户进行此选择?
onItemSelected
。我想等到用户进行选择后再进行处理,该怎么办?可能可以防止这种情况发生(例如没有设置默认值),或者确认是用户进行了选择。我有一个spinner,在对话框视图中显示,当对话框启动时,onItemSelected
被调用。我不想在这个时候处理它,只想在用户进行选择时处理。所以我要么需要阻止这种情况发生(也许因为没有设置默认值?),要么我需要知道不是用户进行此选择?
onItemSelected
。我想等到用户进行选择后再进行处理,该怎么办?可能可以防止这种情况发生(例如没有设置默认值),或者确认是用户进行了选择。在 Bill Mote 的解决方案精神中,另一个选择是将 OnItemSelectedListener
也作为 OnTouchListener
。然后可以在 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) {
// Your selection handling code here
userSelect = false;
}
}
}
将监听器作为 OnItemSelectedListener
和 OnTouchListener
添加到下拉列表中:
SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
你可以简单地加一个 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) {
}
});
isLoaded
变量,因为它比计数器更有意义。 - Mike Richards从API Level 3开始,您可以在Activity中使用onUserInteraction()方法并传递一个布尔值来确定用户是否正在与设备交互。
http://developer.android.com/reference/android/app/Activity.html#onUserInteraction()
@Override
public void onUserInteraction() {
super.onUserInteraction();
userIsInteracting = true;
}
作为活动的一个字段,我有:
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) {
}
});
当您在活动中进出时,布尔值将被重置为false。运作得很好。
Android开发者,我已经找到了一个解决这个问题的方法,并在此处发布(包括代码示例):
我采用了一种不同的方法来解决这个问题,因为我注意到onItemSelected方法有时在方向更改时被调用两次,有时只调用一次。
它似乎取决于当前的下拉列表选择。所以标志或计数器对我没有用。相反,我使用 widgetsRestartTime = System.currentTimeMillis()在onResume()和onCreate中记录系统时间
widgetsRestartTime声明为double和实例变量。
现在,在onItemSelected()方法中,我再次检查当前时间并从中减去widgetsRestartTime,如下所示: if (System.currentTimeMillis() - widgetsRestartTime > 200) { // 用户触发的事件-因此这是一个真正的下拉列表事件,所以要处理它 } else { // 系统生成的事件,例如方向更改、活动启动。所以忽略 }
if(((String)parent.getTag()).equalsIgnoreCase(TAG_SPINNERVALUE))
{
parent.setTag("");
return;
}
另外,这个方法也适用于将同一个监听器设置给多个下拉列表!
if (parentView.getTag() == TAG_INITIALIZING) {parentView.setTag(null);return;}
- rds我曾经遇到同样的问题,通过记住之前选择的下拉框值来解决。在每个onItemSelected调用中,我会将新值与之前的值进行比较,如果相同,就不再进一步处理代码。
对我来说行得通,
私有布尔值isSpinnerInitial = true;
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
if(isSpinnerInitial)
{
isSpinnerInitial = false;
}
else {
// do your work...
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if(pos != 0) {
pos--;
// your code here
}
}
由于选项0永远不可能被选择。干杯 :-)
是的,您所看到的是正确的,并且这是默认行为,您无法阻止它。在初始加载时,OnItemSelected回调会被调用。在此之后,只有当用户更改选择或者您从代码中更改选择时才会触发它。您可以使用一个指示器来告诉您事件是否是初始加载的结果,如果您不想处理第一个事件,则可以忽略它。