RecyclerView嵌套Spinner onItemSelected问题

在使用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) {
            
        }
    };)

修改后达到了想要的效果。


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值