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