recyclerview 的item中包含 edittext,checkbox,button的点击事件相关处理,以及item的删除事件

近期在做一个收银系统,里面用到了

遇见了,一些,checkbox的选中,滑动数据混乱,以及edittext的焦点失去 不能输入,按钮的加减但是显示 数据混乱等bug,

仅以此文章 记录解决方案。

首先,关于checkbox的选中事件是一个老生常谈的问题了,下面直接上解决方案:

思路就是需要通过设置tag ,来确定选中的checkbox 是哪个checkbox .


接着 需要设置,是否默认选中,在列表的数据类中,自定义的bean中,加上一个是否被选中的字段

在适配器中,设置默认显示 是否被选中  同时还有默认的相关数据,如图上 单价,小计,折后价等数据

在适配器中,设置checkbox的选中事件,其实是按钮的点击事件

需要注意的点是:

此处的监听为按钮的点击事件的监听,而不是选中状态改变的监听,需要去进行判断,如果之前为选中状态的话,就需要设置数据list中 相应位置的选中状态为未选中状态 ,此处为关键点。将相关改变的数据 都需要保存到数据列中,对应的位置

2.加减按钮的点击事件


关键点 就是保存与之变化相联动变化的一些值,否则会出现,在列表刷新的时候 ,之前填写的数据,选中的状态被清空。

3.输入框的点击事件

//输入框的编辑事件
holder.editTextDiscountNumber.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(final Editable editable) {
        final int pos=(Integer)holder.editTextDiscountNumber.getTag();
       final int number = StringUtil.toInt(holder.textViewNumber.getText().toString());//当前的购买数量
       final double discountRate = StringUtil.StringToDouble(holder.editTextDiscountRate.getText().toString());//当前折扣
        final double dicountAfterPrice = StringUtil.StringToDouble(holder.textViewAfterDiscountPrice.getText().toString());//折后价

        if (editable == null || StringUtil.isEmpty(editable.toString())) {
            return;
        }

        if(delayRun!=null){
            //每次editText有变化的时候,则移除上次发出的延迟线程
            handler.removeCallbacks(delayRun);
        }
        /**
         * 延迟线程,看是否还有下一个字符输入
         */
         delayRun = new Runnable() {

            @Override
            public void run() {
                //在这里调用服务器的接口,获取数据
                double discountNumber = StringUtil.StringToDouble(editable.toString());//当前优惠金额
                if (discountNumber>dicountAfterPrice*number*discountRate/100){
                    App.showToast("请检查输入的优惠金额");
                    return;
                }
                itemTotalPrice = dicountAfterPrice*number*discountRate/100-discountNumber;//小计
                holder.textViewCommit.setText(DoubleUtils.doubleTrans2(itemTotalPrice)+"");//设置显示的小数点位数

                /*关键点:1.edittext设置tag,此tag用来与position做对比校验,验证当前选中的edittext是否为需要的控件;
                2.焦点判断:只有当前有焦点的edittext才有更改数据的权限,否则会造成数据紊乱
                3.edittext内数据变动直接直接更改datalist的数据值,以便滑动view时显示正确*/
                if (pos == position && holder.editTextDiscountNumber.hasFocus()) {
                    listData.get(pos).setDicountNumber(discountNumber);
                    listData.get(pos).setCommitNumber(itemTotalPrice);
                    sendNote();
                }
            }
        };
        //延迟800ms,如果不再输入字符,则执行该线程的run方法
        handler.postDelayed(delayRun, 800);
    }
});
关于编辑焦点的问题,需要加上
android:focusable="true"><!--必须加上代码-->

这句代码,在item的外层布局中

4.recycleview 的删除事件,任意删除 item,并且保证数据不会混乱


holder.textViewDelete.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        listData.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, getItemCount());
        sendNote();
    }
});

需要注意的点,就是需要将数据移除,需要调用两个方法,来更新数据列 一个是notifyItemRemoved,还有notifyItemRangeChanged 后者主要是用来刷新,被删除的item以及之后到最后item的所有数据,避免出现,position没有及时变更