可能重复:
Android Spinner OnItemSelected Called Erroneously (without user action on opening spinner)
有人知道如何在实例化布局时阻止运行onItemSelected()(OnItemSelectedListener接口)方法吗?我需要知道是否有办法做到这一点,因为我想保持我如何实例化我的布局与该侦听器分开。
我尝试在重写方法内的所有代码周围创建一个最初设置为false的if语句,但是无法知道何时将其设置为true,因为重写的方法在onCreate(),onStart之后运行(每次都是onResume()方法。
我没有找到任何明确的答案。任何明确的解决方案都将受到高度赞赏。
答案 0 :(得分:63)
大卫,这是我为这个问题写的教程......
问题陈述
在Gallery(或Spinner)初始化时触发了一个不合需要的onItemSelected()。 这意味着代码过早地执行;仅在用户进行实际选择时才执行的代码。
<强>解决方案强>
代码示例
public class myActivity extends Activity implements OnItemSelectedListener
{
//this counts how many Gallery's are on the UI
private int mGalleryCount=0;
//this counts how many Gallery's have been initialized
private int mGalleryInitializedCount=0;
//UI reference
private Gallery mGallery;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.myxmllayout);
//get references to UI components
mGallery = (Gallery) findViewById(R.id.mygallery);
//trap selection events from gallery
mGallery.setOnItemSelectedListener(this);
//trap only selection when no flinging is taking place
mGallery.setCallbackDuringFling(false);
//
//do other stuff like load images, setAdapter(), etc
//
//define how many Gallery's are in this view
//note: this could be counted dynamically if you are programmatically creating the view
mGalleryCount=1;
}
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
if (mGalleryInitializedCount < mGalleryCount)
{
mGalleryInitializedCount++;
}
else
{
//only detect selection events that are not done whilst initializing
Log.i(TAG, "selected item position = " + String.valueOf(position) );
}
}
}
为什么会这样?
此解决方案有效,因为Gallery在用户实际进行选择之前很久就完成了初始化。
答案 1 :(得分:12)
以下是“Someone Somewhere”代码的修改版本。如果您只有一个视图,则可以使用它。
public class myActivity extends Activity implements OnItemSelectedListener
{
// Set view initialization to false while the it is being built
private boolean initializedView = false;
//UI reference
private Gallery mGallery;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.myxmllayout);
//get references to UI components
mGallery = (Gallery) findViewById(R.id.mygallery);
//trap selection events from gallery
mGallery.setOnItemSelectedListener(this);
//trap only selection when no flinging is taking place
mGallery.setCallbackDuringFling(false);
//
//do other stuff like load images, setAdapter(), etc
//
}
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
if (initializedView == false)
{
initializedView = true;
}
else
{
//only detect selection events that are not done whilst initializing
Log.i(TAG, "selected item position = " + String.valueOf(position) );
}
}
}
答案 2 :(得分:11)
相同的解决方案:
private int m_intSpinnerInitiCount = 0;
private static final int NO_OF_EVENTS = 1;
...
m_spnTemplates.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position, long id) {
//trying to avoid undesired spinner selection changed event, a known problem
if (m_intSpinnerInitiCount < NO_OF_EVENTS) {
m_intSpinnerInitiCount++;
} else {
//YOUR CODE HERE
}
}
答案 3 :(得分:1)
昨天我用OnCheckedChangedListener遇到了这个问题。我最终在我的适配器类中添加了一个布尔实例变量,并使用访问器方法isListenerEnabled()。然后我在布局代码中将变量设置为false,并在布局代码的末尾再次将其设置为true。在我的监听器中,我检查变量的值以决定是否执行监听器代码。
答案 4 :(得分:1)
每次调用false
时,您都可以将变量设置回onPause
。
至于何时将其设置为true
,您可以在onResume
之后为第一个动作/键/轨迹球事件执行此操作。
答案 5 :(得分: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());
}
}
}