我想过一些不那么优雅的方法来解决这个问题,但我知道我一定遗漏了什么。

我的onItemSelected立即启动,没有与用户进行任何交互,这是不希望的行为。我希望UI能够等到用户选择某样东西后再执行任何操作。

我甚至尝试在onResume()中设置监听器,希望能有所帮助,但它没有。

我怎样才能阻止它在用户可以触摸控件之前发射?

public class CMSHome extends Activity { 

private Spinner spinner;

@Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Heres my spinner ///////////////////////////////////////////
    spinner = (Spinner) findViewById(R.id.spinner);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
            this, R.array.pm_list, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
    };

public void onResume() {
    super.onResume();
    spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
}

    public class MyOnItemSelectedListener implements OnItemSelectedListener {

    public void onItemSelected(AdapterView<?> parent,
        View view, int pos, long id) {

     Intent i = new Intent(CMSHome.this, ListProjects.class);
     i.putExtra("bEmpID", parent.getItemAtPosition(pos).toString());
        startActivity(i);

        Toast.makeText(parent.getContext(), "The pm is " +
          parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
    }

    public void onNothingSelected(AdapterView parent) {
      // Do nothing.
    }
}
}

当前回答

我的解决方案使用onTouchListener,但不限制它的使用。如果需要,它会在设置onItemSelectedListener时为onTouchListener创建一个包装器。

public class Spinner extends android.widget.Spinner {
    /* ...constructors... */

    private OnTouchListener onTouchListener;
    private OnItemSelectedListener onItemSelectedListener;

    @Override
    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
        onItemSelectedListener = listener;
        super.setOnTouchListener(wrapTouchListener(onTouchListener, onItemSelectedListener));
    }

    @Override
    public void setOnTouchListener(OnTouchListener listener) {
        onTouchListener = listener;
        super.setOnTouchListener(wrapTouchListener(onTouchListener, onItemSelectedListener));
    }

    private OnTouchListener wrapTouchListener(final OnTouchListener onTouchListener, final OnItemSelectedListener onItemSelectedListener) {
        return onItemSelectedListener != null ? new OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                Spinner.super.setOnItemSelectedListener(onItemSelectedListener);
                return onTouchListener != null && onTouchListener.onTouch(view, motionEvent);
            }
        } : onTouchListener;
    }
}

其他回答

这是我最后的简单易用的解决方案:

public class ManualSelectedSpinner extends Spinner {
    //get a reference for the internal listener
    private OnItemSelectedListener mListener;

    public ManualSelectedSpinner(Context context) {
        super(context);
    }

    public ManualSelectedSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ManualSelectedSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setOnItemSelectedListener(@Nullable OnItemSelectedListener listener) {
        mListener = listener;
        super.setOnItemSelectedListener(listener);
    }

    public void setSelectionWithoutInformListener(int position){
        super.setOnItemSelectedListener(null);
        super.setSelection(position);
        super.setOnItemSelectedListener(mListener);
    }

    public void setSelectionWithoutInformListener(int position, boolean animate){
        super.setOnItemSelectedListener(null);
        super.setSelection(position, animate);
        super.setOnItemSelectedListener(mListener);
    }
}

使用默认的setSelection(…)作为默认行为,或者使用setSelectionWithoutInformListener(…)在旋转器中选择一个项目而不触发OnItemSelectedListener回调。

这不是一个完美的解决方案,但如果你喜欢将起始字符串作为一个占位符,你可以添加占位符弹簧值("Day_of_Work_Out")

  @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            String name = (String) parent.getItemAtPosition(position);
            if (name.equals("Day_of_Work_Out")) {

            }else {

                workOutD = name;
                Intent intent = new Intent();
                workOutNam = workOutName.getText().toString();

                if (workOutNam == null) {

                    startActivity(intent);
                    Log.i("NewWorkOutActivity","Name is null");

                }else {
                    Log.i("NewWorkOutActivity","Name Not null");
                    Toast.makeText(NewWorkOutActivity.this, "Please Select a Day", Toast.LENGTH_LONG).show();
                }


            }
        }

如果你在代码中进行选择,就会发生这种情况;

mSpinner.setSelection(0);

代替上述语句

mSpinner.setSelection(0,false);//只是简单地不动画它

编辑:此方法不适用于Mi Android版本的Mi UI。

使用Runnables是完全错误的。

使用setSelection(position, false);在setOnItemSelectedListener(listener)之前的初始选择中

通过这种方式,您可以在没有动画的情况下设置您的选择,这将导致被选中的监听器被调用。但是监听器是空的,所以什么都没有运行。然后分配你的听众。

所以按照这个顺序来做吧:

Spinner s = (Spinner)Util.findViewById(view, R.id.sound, R.id.spinner);
s.setAdapter(adapter);
s.setSelection(position, false);
s.setOnItemSelectedListener(listener);

如果你需要在飞行中重新创建活动,例如:改变主题,一个简单的标志/计数器不会工作

使用onUserInteraction()函数检测用户活动,

参考资料:https://stackoverflow.com/a/25070696/4772917