Spinner onItemSelected() выполняется ненадлежащим образом

Возможный дубликат:
Android Spinner OnItemSelected Called Erroneously (без действий пользователя при открытии счетчика)

Кто-нибудь знает, как запретить запуск метода onItemSelected() (OnItemSelectedListener) при создании экземпляра макета? Мне нужно знать, есть ли способ сделать это, потому что я хочу сохранить, как я создаю свой макет отдельно от этого слушателя.

Я попытался создать оператор if, первоначально установленный в false для всего кода внутри переопределенного метода, но нет способа узнать, когда установить его в true, потому что переопределенный метод запускается после onCreate(), onStart ( ) и onResume() каждый раз.

Я не нашел никаких четких ответов на это. Будем очень благодарны за любые решения с четкими разрезами.

Ответ 1

Дэвид, вот учебник, который я написал для этой проблемы...

Заявление о проблемах

запускается нежелательная функция onItemSelected(), в то время как Gallery (или Spinner) инициализируется. Это означает, что код преждевременно выполняется; код, который предназначен для выполнения ТОЛЬКО, когда пользователь физически делает выбор.

Решение

  • в onCreate(), подсчитайте, сколько виджета Gallery (или Spinner) у вас есть в представлении. (MGalleryCount)
  • в onItemSelected(), подсчитайте, как часто он запускается. (MGalleryInitializedCount)
  • когда (mGalleryInitializedCount < mGalleryCount) == false, затем выполните код, предназначенный для пользователя

Пример кода

public class myActivity extends Activity implements OnItemSelectedListener
{
    //this counts how many Gallery are on the UI
    private int mGalleryCount=0;

    //this counts how many Gallery 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 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) );
        }

    }

}

Почему это работает

это решение работает, потому что Галерея заканчивает инициализацию задолго до того, как пользователь физически сможет сделать выбор.

Ответ 2

Вот модифицированная версия кода "Кто-то Где-то". Вы можете использовать его, если у вас есть один вид.

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

}
}

Ответ 3

То же решение:

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

Ответ 4

Я столкнулся с этой проблемой вчера с помощью OnCheckedChangedListener. Я закончил добавление переменной логического экземпляра, инициализированной true в моем классе адаптера, с помощью метода accessListenerEnabled(). Затем я установил переменную в false в мой код макета и снова установил ее в конце кода макета. В моем слушателе я проверяю значение переменной, чтобы решить, следует ли выполнять код слушателя или нет.

Ответ 5

Вы можете вернуть переменную обратно к false каждый раз при вызове onPause. Что касается того, когда установить его на true, вы можете сделать это для первого события motion/key/trackball после onResume.

Ответ 6

Я также искал хорошее решение в Интернете, но не нашел того, что удовлетворяло мои потребности. Поэтому я написал это расширение в классе 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());
        }
    }
}