java-Spinner onItemSelected()执行不当

可能重复:
Android Spinner OnItemSelected被错误调用(在打开Spinner时没有用户操作)

有谁知道如何在实例化布局时阻止onItemSelected()(OnItemSelectedListener接口)方法运行? 我需要知道是否有一种方法可以这样做,因为我想保持实例化布局的方式与此侦听器分开。

我尝试过创建一个if语句,该语句最初在被覆盖的方法内部的所有代码周围都设置为false,但是无法知道何时将其设置为true,因为被覆盖的方法在onCreate(),onStart()和 每次都使用onResume()方法。

我还没有找到任何明确的答案。 任何明确的解决方案将不胜感激。

David asked 2020-08-01T12:05:57Z
6个解决方案
64 votes

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

问题陈述

画廊(或微调器)正在初始化时,触发了不良的onItemSelected()。这意味着代码会过早执行; 仅在用户实际进行选择时才执行的代码。

  1. 在onCreate()中,计算视图中有多少个Gallery(或Spinner)小部件。 (mGalleryCount)
  2. 在onItemSelected()中,计算它触发的频率。 (mGalleryInitializedCount)
  3. 当(mGalleryInitializedCount <mGalleryCount)== false时,执行针对用户的代码

代码示例

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在用户实际能够进行选择之前就完成了初始化。

Someone Somewhere answered 2020-08-01T12:06:53Z
13 votes

这是“某处某人”代码的修改版本。 如果您有一个视图,则可以使用它。

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

}
}
Kalimah Apps answered 2020-08-01T12:07:14Z
11 votes

相同的解决方案:

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
                    }                           
            }
Dimitar Vukman answered 2020-08-01T12:07:33Z
1 votes

我昨天遇到了一个OnCheckedChangedListener这个问题。 我最终在访问器方法isListenerEnabled()的适配器类内部添加了一个初始化为true的布尔实例变量。 然后,在布局代码中将变量设置为false,并在布局代码的末尾再次将其设置为true。 在侦听器中,我检查变量的值,以决定是否执行侦听器代码。

James answered 2020-08-01T12:07:54Z
1 votes

您可以在每次调用onPause时将变量设置回false。至于何时将其设置为true,您可以在onResume之后的第一个运动/键/轨迹球事件中执行此操作。

Joseph Earl answered 2020-08-01T12:08:14Z
1 votes

我也在互联网上寻找了一个好的解决方案,但没有找到满足我需求的解决方案。因此,我已在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());
        }
    }
}
Cliffus answered 2020-08-01T12:08:43Z
translate from https://stackoverflow.com:/questions/5624825/spinner-onitemselected-executes-inappropriately