我想过一些不那么优雅的方法来解决这个问题,但我知道我一定遗漏了什么。
我的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.
}
}
}
在遇到同样的问题后,我想出了这个使用标签的解决方案。
它背后的思想很简单:无论何时以编程方式更改旋转器,都要确保标记反映所选的位置。然后在侦听器中检查所选位置是否等于标记。如果是,则以编程方式更改了旋转器选择。
下面是我的新“spinner proxy”类:
package com.samplepackage;
import com.samplepackage.R;
import android.widget.Spinner;
public class SpinnerFixed {
private Spinner mSpinner;
public SpinnerFixed(View spinner) {
mSpinner = (Spinner)spinner;
mSpinner.setTag(R.id.spinner_pos, -2);
}
public boolean isUiTriggered() {
int tag = ((Integer)mSpinner.getTag(R.id.spinner_pos)).intValue();
int pos = mSpinner.getSelectedItemPosition();
mSpinner.setTag(R.id.spinner_pos, pos);
return (tag != -2 && tag != pos);
}
public void setSelection(int position) {
mSpinner.setTag(R.id.spinner_pos, position);
mSpinner.setSelection(position);
}
public void setSelection(int position, boolean animate) {
mSpinner.setTag(R.id.spinner_pos, position);
mSpinner.setSelection(position, animate);
}
// If you need to proxy more methods, use "Generate Delegate Methods"
// from the context menu in Eclipse.
}
在Values目录中还需要一个带有标记设置的XML文件。
我将我的文件命名为spinner_tag.xml,但这取决于您。
它是这样的:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<item name="spinner_pos" type="id" />
</resources>
现在取代
Spinner myspinner;
...
myspinner = (Spinner)findViewById(R.id.myspinner);
在你的代码中
SpinnerFixed myspinner;
...
myspinner = new SpinnerFixed(findViewById(R.id.myspinner));
让你的处理器看起来像这样:
myspinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (myspinner.isUiTriggered()) {
// Code you want to execute only on UI selects of the spinner
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
函数isUiTriggered()当且仅当旋转器已被用户更改时将返回true。注意,这个函数有一个副作用——它会设置标记,所以同一个监听器调用中的第二个调用总是返回false。
这个包装器还将处理在布局创建期间调用侦听器的问题。
玩得开心,
延斯。
布尔标志或计数器的解决方案没有帮助我,因为在方向变化onItemSelected()调用“飞越”标志或计数器。
我子类化了android.widget.Spinner,并做了一些小的补充。相关部分如下。这个解决方案对我很有效。
private void setHandleOnItemSelected()
{
final StackTraceElement [] elements = Thread.currentThread().getStackTrace();
for (int index = 1; index < elements.length; index++)
{
handleOnItemSelected = elements[index].toString().indexOf("PerformClick") != -1; //$NON-NLS-1$
if (handleOnItemSelected)
{
break;
}
}
}
@Override
public void setSelection(int position, boolean animate)
{
super.setSelection(position, animate);
setHandleOnItemSelected();
}
@Override
public void setSelection(int position)
{
super.setSelection(position);
setHandleOnItemSelected();
}
public boolean shouldHandleOnItemSelected()
{
return handleOnItemSelected;
}
设计一种通用的转轮,只需数据输入,由用户选择,优点:
1. 保持旋转样式相同的应用程序。
2. 在任何地方启动旋转器。
3.易于处理链接转轮(重新启动ReuseSpinner与不同的数据)。
我的演示示例:ReuseSpinner
传递数据到ReuseSpinner:
Intent intent = new Intent(MainActivity.this, SpinnerActivity.class);
intent.putExtra(SpinnerActivity.Extra_Resource, arrayList);
startActivityForResult(intent, mRequestCode_select_country_prompt);
获取用户选择:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == mRequestCode_select_country && resultCode == RESULT_OK){
if(data != null){
Map.Entry<String,String> entry = (Map.Entry<String,String>) data.getSerializableExtra(SpinnerActivity.Result_Data);
if(entry != null){
Log.i(TAG, String.format("get result -> key:%s , value:%s", entry.getKey(), entry.getValue()));
}
}
}
}