Android 微调器被错误地调用(没有用户操作)
我有一个在对话框视图中显示的微调器,对话框启动的那一刻即被调用。我真的不想处理这个,但只有当用户做出选择时。因此,我需要防止这种情况发生(可能是因为没有设置默认值?),或者我需要知道不是用户做出了选择?是的,您看到的是正确的,是默认行为,您无法防止这种情况发生。初始加载时调用OnItemSelected回调。在初始加载之后,只有当用户更改选择或您从代码中更改选择时,才会触发该选项。您可以有一个指示器,它可以告诉您事件是否是初始加载的结果,如果您不想处理它,则可以忽略第一个事件 Androider,我已经找到了这个问题的解决方案,并将其发布在这里(带有代码示例):Android 微调器被错误地调用(没有用户操作),android,spinner,android-spinner,Android,Spinner,Android Spinner,我有一个在对话框视图中显示的微调器,对话框启动的那一刻即被调用。我真的不想处理这个,但只有当用户做出选择时。因此,我需要防止这种情况发生(可能是因为没有设置默认值?),或者我需要知道不是用户做出了选择?是的,您看到的是正确的,是默认行为,您无法防止这种情况发生。初始加载时调用OnItemSelected回调。在初始加载之后,只有当用户更改选择或您从代码中更改选择时,才会触发该选项。您可以有一个指示器,它可以告诉您事件是否是初始加载的结果,如果您不想处理它,则可以忽略第一个事件 Androider
我用另一种方法解决了这个问题,因为我注意到有时在方向更改时调用两次或一次onItemSelected方法 它似乎取决于当前的微调器选择。所以旗子或计数器对我不起作用。相反,我在onResume()和onCreate中使用 widgetsRestartTime=System.currentTimeMillis() widgetsRestartTime声明为double和intance变量 现在,在onItemSelected()方法中,我再次检查当前时间并从中减去widgetsRestartTime,如下所示: 如果(System.currentTimeMillis()-widgetsRestartTime>200){ //用户触发的事件-所以这是一个真正的微调器事件,所以请处理它 }否则{ //系统生成的事件,例如方向更改、活动启动。因此忽略
}我还在互联网上寻找一个好的解决方案,但没有找到任何能满足我需求的解决方案。 因此,我在Spinner类上编写了这个扩展,因此您可以设置一个简单的Listener,它与ListView具有相同的行为 只有当一个项目被“选中”时,才会调用McClickListener 玩得开心
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());
}
}
}
您只需添加一个int计数即可解决此问题:)
sp.setOnItemSelectedListener(新的OnItemSelectedListener(){
整数计数=0;
@凌驾
已选择公共视图(AdapterView arg0、视图arg1、内部arg2、长arg3){
如果(计数>=1){
int item=sp.getSelectedItemPosition();
Toast.makeText(getBaseContext(),
您已选择书籍:“+androidBooks[项目],
吐司。长度(短)。show();
}
计数++;
}
@凌驾
未选择公共无效(AdapterView arg0){
}
});
我也遇到了同样的问题,我通过记住以前选择的微调器值解决了这个问题。在每次选中的调用中,我都会将新值与前一个值进行比较,如果相同,我不会进一步处理代码 我也有同样的问题。但是被接受的解决方案对我不起作用,因为我的表单上有多个微调器,其中一些是隐藏的,当微调器被隐藏时,侦听器不会启动,因此计数对我来说不是一个解决方案
我找到了另一个解决方案,不过:
if(((String)parent.getTag()).equalsIgnoreCase(TAG_SPINNERVALUE))
{
parent.setTag("");
return;
}
另外,这适用于设置为多个微调器的同一侦听器 如果你也在买一个,你可以一起去
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if(pos != 0) {
pos--;
// your code here
}
}
@覆盖
已选择公共位置(AdapterView父项、视图、整数位置、长id){
如果(位置!=0){
pos--;
//你的代码在这里
}
}
因为项目0永远无法选择。干杯:-)从API级别3开始,您可以对带有布尔值的活动使用onUserInteraction(),以确定用户是否正在与设备交互 作为活动的一个字段,我有:
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) {
}
});
mSpinnerView.setOnItemSelectedListener(新的OnItemSelectedListener(){
@凌驾
已选择公共位置(AdapterView arg0、视图、整型位置、长arg3){
spinnerAdapter.setmPreviousSelectedIndex(位置);
如果(用户交互){
updateGUI();
}
}
@凌驾
未选择公共无效(AdapterView arg0){
}
});
当您在活动中来回走动时,布尔值将重置为false。工作起来很有魅力。对我来说很有效
private boolean isspinnerinital=true代码>
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
if(isSpinnerInitial)
{
isSpinnerInitial = false;
}
else {
// do your work...
}
}
@覆盖
已选择公共视图(AdapterView父视图、视图、,
内部位置,长id){
如果(初始值)
{
isSpinnerInitial=false;
}
否则{
//做你的工作。。。
}
}
比尔·莫特解决方案的另一个选择是使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;
}
}
}
你应该这样做。顺序是关键
spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);
如果你不介意使用promt的职位,那么每次你想在spinner上工作时,你都可以这样做。promt的第一组选择:
spinner.setselected(0);
spinner.add("something");
...
然后在选择发生时执行类似操作:
spinner.ItemSelected += (object sender, AdapterView.ItemSelectedEventArgs e) =>
{
if (spinner.SelectedItemPosition != 0)
{
//do staff
}
}
您可以尝试使用两个参数设置微调器,如下所示:
spinner.setSelection(count, false);
spinner.setselected(0);
spinner.add("something");
...
spinner.ItemSelected += (object sender, AdapterView.ItemSelectedEventArgs e) =>
{
if (spinner.SelectedItemPosition != 0)
{
//do staff
}
}
spinner.setSelection(count, false);
spinner.setSelection(0,false);