После того, как у меня возникла та же проблема, я пришел к этому решению, используя теги.
Идея этого проста: всякий раз, когда прядильщик изменяется программно, убедитесь, что тег отражает выбранную позицию. Затем в слушателе вы проверяете, соответствует ли выбранная позиция тегу. Если это так, выбор счетчика был изменен программно.
Ниже приведен мой новый класс "Spinner Proxy":
package com.samplepackage;
import com.samplepackage.R;
import android.widget.Spinner;
public class SpinnerFixed {
private Spinner mSpinner;
public SpinnerFixed(View spinner) {
mSpinner = (Spinner)spinner;
mSpinner.setTag(R.id.spinner_pos, -2);
}
public boolean isUiTriggered() {
int tag = ((Integer)mSpinner.getTag(R.id.spinner_pos)).intValue();
int pos = mSpinner.getSelectedItemPosition();
mSpinner.setTag(R.id.spinner_pos, pos);
return (tag != -2 && tag != pos);
}
public void setSelection(int position) {
mSpinner.setTag(R.id.spinner_pos, position);
mSpinner.setSelection(position);
}
public void setSelection(int position, boolean animate) {
mSpinner.setTag(R.id.spinner_pos, position);
mSpinner.setSelection(position, animate);
}
// If you need to proxy more methods, use "Generate Delegate Methods"
// from the context menu in Eclipse.
}
Вам также понадобится файл XML с настройкой тега в каталоге Values
.
Я назвал свой файл spinner_tag.xml
, но это зависит от вас.
Это выглядит так:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<item name="spinner_pos" type="id" />
</resources>
Теперь замените
Spinner myspinner;
...
myspinner = (Spinner)findViewById(R.id.myspinner);
в вашем коде с
SpinnerFixed myspinner;
...
myspinner = new SpinnerFixed(findViewById(R.id.myspinner));
И сделайте так, чтобы ваш обработчик выглядел примерно так:
myspinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (myspinner.isUiTriggered()) {
// Code you want to execute only on UI selects of the spinner
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Функция isUiTriggered()
вернет истину тогда и только тогда, когда пользователь изменил счетчик. Обратите внимание, что эта функция имеет побочный эффект - она устанавливает тег, поэтому второй вызов в том же вызове слушателя всегда будет возвращать false
.
Эта оболочка также решит проблему с вызовом слушателя во время создания макета.
Веселись,
Jens.