Spinner onItemSelected()执行不当

时间:2011-04-11 17:02:28

标签: java android

  

可能重复:
  Android Spinner OnItemSelected Called Erroneously (without user action on opening spinner)

有人知道如何在实例化布局时阻止运行onItemSelected()(OnItemSelectedListener接口)方法吗?我需要知道是否有办法做到这一点,因为我想保持我如何实例化我的布局与该侦听器分开。

我尝试在重写方法内的所有代码周围创建一个最初设置为false的if语句,但是无法知道何时将其设置为true,因为重写的方法在onCreate(),onStart之后运行(每次都是onResume()方法。

我没有找到任何明确的答案。任何明确的解决方案都将受到高度赞赏。

6 个答案:

答案 0 :(得分:63)

大卫,这是我为这个问题写的教程......

问题陈述

在Gallery(或Spinner)初始化时触发了一个不合需要的onItemSelected()。 这意味着代码过早地执行;仅在用户进行实际选择时才执行的代码。

<强>解决方案

  1. 在onCreate()中,计算视图中有多少个Gallery(或Spinner)小部件。 (mGalleryCount)
  2. 在onItemSelected()中,计算它触发的频率。 (mGalleryInitializedCount)
  3. 当(mGalleryInitializedCount&lt; mGalleryCount)== false时,然后执行适合用户的代码
  4. 代码示例

    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());
        }
    }
}