最近写项目用到了spinner,要求点击item 进行跳转操作,但是当我返回到包含spinner的activity中,再次点击相同的item无法实现跳转操作。研究了半天才发现原因,Android spinner本身记住了上一次选择的项,再次点击相同的项是不会触发onitemselected事件的。
看下源码 发现spinner判断 是否触发onitemselected,是在基类adapterView中做的。
void checkSelectionChanged() {
if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) {
selectionChanged();
mOldSelectedPosition = mSelectedPosition;
mOldSelectedRowId = mSelectedRowId;
}
}
方法
checkSelectionChanged
和变量
mOldSelectedPosition
都是
AdapterView
私有的,我们无法继承
Spinner
重写之。不过,利用
java
的反射,我们可以暴力修改
mOldSelectedPosition
的值:
new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
try {
//以下三行代码是解决问题所在
Field field = AdapterView.class.getDeclaredField("mOldSelectedPosition");
field.setAccessible(true); //设置mOldSelectedPosition可访问
field.setInt(spinner, AdapterView.INVALID_POSITION); //设置mOldSelectedPosition的值
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
我们每次选择之后,就更改
mOldSelectedPosition
的值,使得每次
mSelectedPosition != mOldSelectedPosition
判断总是为
true
,那么总会触发
onItemSelected
,达到我们的目的了。