我有一个微调器,我在对话框视图中显示,并且对话框启动的那一刻onItemSelected
被调用。我真的不想处理这个,但只有当用户做出选择时。所以我要么要防止这种情况(可能是因为没有设置默认值?),或者我需要知道是不是用户正在进行此选择?
答案 0 :(得分:41)
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);
答案 1 :(得分:21)
你可以简单地添加一个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) {
}
});
答案 2 :(得分:8)
从API级别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。像魅力一样。
答案 3 :(得分:6)
Androider,我找到了解决这个问题的方法并在此处发布(带代码示例):
答案 4 :(得分:4)
我已经用不同的方式解决了这个问题,因为我注意到有时onItemSelected方法在方向更改时调用了两次,有时甚至一次。
这似乎取决于当前的微调器选择。因此,旗帜或柜台对我不起作用。相反,我用BOTH onResume()和onCreate记录系统时间 widgetsRestartTime = System.currentTimeMillis()
widgetsRestartTime被声明为double和intance变量。
现在在onItemSelected()方法中,我再次检查当前时间并从中减去widgetsRestartTime,如下所示: if(System.currentTimeMillis() - widgetsRestartTime&gt; 200){ //用户触发的事件 - 所以这是一个真正的微调器事件,所以处理它 } else { //系统生成事件,例如方向改变,活动启动。所以忽略 }
答案 5 :(得分:3)
是的,您所看到的是正确的并且是默认行为,您无法阻止这种情况。在初始加载时调用OnItemSelected回调。在初始加载之后,只有在用户更改选择或您在代码中更改选择时才会触发它。您可以使用一个指示器来告诉您事件是否是初始加载的结果,如果您不想处理它,则忽略第一个事件。
答案 6 :(得分:3)
我遇到了同样的问题,我通过记住之前选择的微调器值来解决它。在每个onItemSelected调用中,我将新值与前一个值进行比较,如果它是相同的,我不会进一步处理代码。
答案 7 :(得分:3)
我遇到了同样的问题。但是接受的解决方案并不适用于我,因为我的表单上有多个微调器,其中一些是隐藏的,当旋转器被隐藏时,监听器不会触发,因此计数对我来说不是解决方案。
我找到了另一种解决方案:
就是这样,它就像一个魅力!
监听器中的示例:
if(((String)parent.getTag()).equalsIgnoreCase(TAG_SPINNERVALUE))
{
parent.setTag("");
return;
}
P.S。这适用于设置为多个微调器的同一个监听器!
答案 8 :(得分:2)
如果您还在购买initially unselected Spinner,则可以使用
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if(pos != 0) {
pos--;
// your code here
}
}
由于永远无法选择第0项。干杯: - )
答案 9 :(得分:2)
它对我有用,
private boolean isSpinnerInitial = true;
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
if(isSpinnerInitial)
{
isSpinnerInitial = false;
}
else {
// do your work...
}
}
答案 10 :(得分:1)
我也在互联网上寻找一个很好的解决方案,但没有找到任何满足我需求的解决方案。 所以我在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());
}
}
}
答案 11 :(得分:1)
你应该这样做。顺序是关键。
spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);
答案 12 :(得分:1)
您可以尝试使用两个参数设置微调器,如下所示:
spinner.setSelection(count, false);
所以,把它放在OnItemSelectedListener:
之前spinner.setSelection(0,false);
您可以从开发者页面查看更多内容:
https://developer.android.com/reference/android/widget/Spinner.html
答案 13 :(得分:0)
如果你不介意使用某个职位,你可以在每次想要在微调器上做员工时做这样的事情。首先选择promt:
spinner.setselected(0);
spinner.add("something");
...
然后在选择发生时做类似的事情:
spinner.ItemSelected += (object sender, AdapterView.ItemSelectedEventArgs e) =>
{
if (spinner.SelectedItemPosition != 0)
{
//do staff
}
}
答案 14 :(得分:0)
问题是我们在微调器完成渲染之前设置了侦听器。一旦呈现,它会自动选择它的数据集第一个选项(这很好),但这会导致我们的侦听器触发。
解决办法是等待特定的spinner布局好,然后才设置监听器:
binding.spinnerLanguage.post( new Runnable() {
@Override
public void run() {
binding.spinnerLanguage.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
GeneralUtils.log(TAG, "finally, not triggering on initial render");
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
});