我想过一些不那么优雅的方法来解决这个问题,但我知道我一定遗漏了什么。
我的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来区分对setOnItemSelectedListener的自动调用(这是Activity初始化的一部分,等等)与实际用户交互触发的对它的调用之间的提示,在尝试了其他一些建议后,我做了以下工作,并发现它用最少的代码行就能很好地工作。
只需要为你的Activity/Fragment设置一个布尔字段:
private Boolean spinnerTouched = false;
然后在你设置你的旋转器的setOnItemSelectedListener之前,设置一个onTouchListener:
spinner.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("Real touch felt.");
spinnerTouched = true;
return false;
}
});
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
...
if (spinnerTouched){
//Do the stuff you only want triggered by real user interaction.
}
spinnerTouched = false;
这不是一个完美的解决方案,但如果你喜欢将起始字符串作为一个占位符,你可以添加占位符弹簧值("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();
}
}
}
在抽出我的头发很长一段时间后,现在我已经创建了自己的Spinner类。我已经添加了一个方法,它可以适当地断开和连接侦听器。
public class SaneSpinner extends Spinner {
public SaneSpinner(Context context) {
super(context);
}
public SaneSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SaneSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// set the ceaseFireOnItemClickEvent argument to true to avoid firing an event
public void setSelection(int position, boolean animate, boolean ceaseFireOnItemClickEvent) {
OnItemSelectedListener l = getOnItemSelectedListener();
if (ceaseFireOnItemClickEvent) {
setOnItemSelectedListener(null);
}
super.setSelection(position, animate);
if (ceaseFireOnItemClickEvent) {
setOnItemSelectedListener(l);
}
}
}
在XML中像这样使用它:
<my.package.name.SaneSpinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/mySaneSpinner"
android:entries="@array/supportedCurrenciesFullName"
android:layout_weight="2" />
你所要做的就是在膨胀和调用集选择之后检索SaneSpinner实例:
mMySaneSpinner.setSelection(1, true, true);
这样,就不会触发任何事件,用户交互也不会中断。这大大降低了我的代码复杂性。这应该包括在Android的股票,因为它确实是一个PITA。