在使用RecyclerView嵌套Spinner时会出现这样一个问题,当recyclerView翻页后更改spinner的selection状态,此时不会触发刚才点击的spinner的itemselected事件而是直接去刷新整个recyclerview,导致设置spinner状态失败。
经过分析发现,当某个item的spinner状态改变过后,recyclerview会重新刷新,导致会触发某几个item(之前未显示在屏幕上而之后需要显示在屏幕上的item)的itemselected事件,此时并不能定位刚才点击的是recyclerview的哪个item中的spinner的位置(表达不清,感觉把自己都绕进去了,还是上图把)。
所以onItemSelectedListener是肯定用不了的,开始想其他办法:1、不使用Spinner,改用其他控价;2、使用其他事件代替实现onItemSelected的效果。想了想,1还是算了,懒得再写多余的代码了,考虑用2的方式来实现,于是开始查看Spinner的api,发现了一个setOnItemClickListenerInt的api但是不对外提供,所以这里想到了用反射来调用setOnItemClickListenerInt,代码如下
public class MySpinner extends Spinner {
private ItemClick mItemClick;
public MySpinner(Context context) {
super(context);
init();
}
public MySpinner(Context context, int mode) {
super(context, mode);
init();
}
public MySpinner(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MySpinner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public MySpinner(Context context, AttributeSet attrs, int defStyleAttr, int mode) {
super(context, attrs, defStyleAttr, mode);
init();
}
public MySpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode) {
super(context, attrs, defStyleAttr, defStyleRes, mode);
init();
}
public MySpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode, Resources.Theme popupTheme) {
super(context, attrs, defStyleAttr, defStyleRes, mode, popupTheme);
init();
}
public void setItemClick(ItemClick mItemClick) {
this.mItemClick = mItemClick;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void init() {
Class<?> myClass = Spinner.class;
try {
Class<?>[] params = new Class[1];
params[0] = OnItemClickListener.class;
Method m = myClass.getDeclaredMethod("setOnItemClickListenerInt", params);
m.setAccessible(true);
m.invoke(this, new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Class<?> myClass = AdapterView.class;
try {
Field field = myClass.getDeclaredField("mOldSelectedPosition");
field.setAccessible(true);
field.setInt(MySpinner.this, AdapterView.INVALID_POSITION);
mItemClick.onClick(position);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
});
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
}
public interface ItemClick {
void onClick(int position);
}
}
如何使用?
spinner.setItemClick(new ItemClick() {
@Override
public void onClick(int position) {
}
};)
修改后达到了想要的效果。
|