RecycleView列表Item中包含EditText的爬坑笔记

前言:

  就我个人的开发经验而言,无论单商城还是多商城App,购物车部分编辑商品数量,都是使用“+”和“-”这种形式实现的,这种形式适用商品数量是整数型的,如果对于商品数量可能存在小数的需求,显然上述形式,没有办法满足需求,要想实现商品数量可能存在小数这样的需求,估计只能列表Item中使用EditText来实现。这样实现需求,即使我也知道,无数坑在前方向我招手,实属无奈!!!

废话不多说,看图看需求:
需求.png
需求分析:
  • 列表中需要编辑数量,使用RecycleView结合EditText实现;
  • 输入金额不符合要求(低于起订量),刷新界面(暂时认为是刷新界面),进行提示(输入金额低于起订量)显示;
初步考虑:
  • 考虑recycleView对item的复用性,item中编辑框会出现错乱,彼此相互影响的问题;

正文:

按照需求分析开发过程中,我遇到了很多坑,在这里记录几个关键的坑以及爬坑方法。

一号坑:输入框输入数量,总计联动;

解决方式:

1:在adapter中对输入框监听输入内容,通过接口将输入内容回调到activity中;
1.1:创建接口;
1.2:adapter中,构造方法中获取接口对象,onBindViewHolder方法中监听回传数据;
2:activity中创建map接收商品id和商品数量的对应关系,回调方法中根据输入内容 是否为空,添加删除指定数据;
2.1:创建map接收商品Id和商品数量对应关系
2.2:回调方法中编辑map中数据
代码按照顺序如下:

public interface ItemEditGetInfoListener {
    void getUserInPutInfo(int position, String str);
}
    public TiLiaoGoodsAdapter(Context context, List<TiLiaoGoodsSelectBean.DataBean.GoodsBean.GoodsListBean> list) {
        this.context = context;
        this.lists = list;
//activity中实现这个接口,获取接口对象
        this.listener=(ItemEditGetInfoListener)context;
        this.deleteListener=(ItemDeleteGetPositionListener)context;
    }
TextWatcher whatch=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) {
                String input=editable.toString();
          
                listener.getUserInPutInfo(position,editable.toString());

            }
        };
        //添加监听
        holder.mEtNum.addTextChangedListener(whatch);
private Map<String, Double> goodIdNumMap =new HashMap<>();
    @Override
    public void getUserInPutInfo(int position, String str) {

        Logger.d("用户输入信息位置"+position+"输入内容"+str);
      //如果用户输入内容不是空,添加数据,输入内容为空,就需要删除数据
        if(!TextUtils.isEmpty(str)){
            goodIdNumMap.put(uiLists.get(position).getGoodsId(),Double.valueOf(str));
        }else{
            goodIdNumMap.remove(uiLists.get(position).getGoodsId());
        }
//对map中数据进行遍历,计算金额和总数量并展示
        setGoodsInfoToButtomUi();
    }

二号坑:输入数量不符合要求,进行提示

初步思路

监听输入框输入内容,当用户输入完成(1s前后输入是否一致判定是否输入完成)后,判定输入内容是否符合内容,符合不做处理,不符合,进行手动刷新,代码比较简单,就不贴出来了,思路是对的,但是实际开发过程中又引出另外几个坑。。。。。
1:刷新界面,由于复用性,输入框内容会出现错乱的问题;
解决办法

  • adapter中创建map记录position和输入框num的对应关系,刷新之后,手动赋值;
  • 禁用recycleView的复用性(这种方法测试的时候效果不明显):
@Override
   public void onBindViewHolder(final MyViewHolder holder, final int position) {
//禁用复用性
       holder.setIsRecyclable(false);
    setGoodsInfoToUI(holder,position);
   }

2:刷新界面,会导致EditText监听错乱,反复执行,导致数据错乱;
解决办法:对EidtText使用TextWatcher做标记,添加之前先移除之前添加的监听,见代码:

    private void setListener(final MyViewHolder holder, final int position, final TiLiaoGoodsSelectBean.DataBean.GoodsBean.GoodsListBean bean) {
        //刷新界面的时候会触发textwatcher监听,需要提前将其移除,防止数据错乱
        //参考:https://blog.csdn.net/qq953655369/article/details/72910578
        //参考:https://www.jianshu.com/p/db4891bfd213
        if(holder.mEtNum.getTag() instanceof  TextWatcher){
            holder.mEtNum.removeTextChangedListener((TextWatcher) holder.mEtNum.getTag());
        }
        TextWatcher whatch=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) {
        };
        //添加监听
        holder.mEtNum.addTextChangedListener(whatch);
        //设置标记,为了上面删除监听使用
        holder.mEtNum.setTag(whatch);
    }

3:刷新界面,界面上的焦点光标消失(刷新界面,导致界面焦点改变导致的),用户体验非常不好(用户输入完成后,刷新界面,发现输入的不符合要求,想重新编辑的话,需求重新点击该编辑框,让其重新获取焦点)。
  最后这个坑,按照这个思路,我真是绞尽脑汁,最终没解决。汗颜!!!需求只能开发到这里,虽然冲破重重关卡,解决无数坑,走到这里终究不完美,心有不甘啊!!!回头看看自己写的代码,有一句总结:话说当recycleView的item中有Edittext,刷新界面的时候,真是无数坑啊!最终这个大坑没解决。哎!等等,既然刷新界面这么多问题,能不能不刷新界面,实现刷新界面的效果呢?有这个想法的时候,我仿佛在绝望中看到了希望,顺着这个思路,最终还是找到了解决办法。

最终思路(最终解决办法),思路如下:

1:分别创建map对象,用于处理订单id和用户输入数量不合规需要特殊处理的控件对应关系;
private HashMap<String,View>mTvHintMap=new HashMap<>();
    private HashMap<String,View>rlEditMap=new HashMap<>();
    private HashMap<String,View>mEtNumMap=new HashMap<>();
@Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
      mTvHintMap.put(bean.getGoodsId(),holder.mTvHint);
        mEtNumMap.put(bean.getGoodsId(),holder.mEtNum);
        rlEditMap.put(bean.getGoodsId(),holder.rlEdit);
    }
2:当用户真正输入数量不合规的时候,只需要根据id,去map中取出对应的控件,根据相应的业务逻辑对控件进行展示特殊处理(重点看整体的解决思路,业务逻辑部分没必要看);
@Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
      mTvHintMap.put(bean.getGoodsId(),holder.mTvHint);
        mEtNumMap.put(bean.getGoodsId(),holder.mEtNum);
        rlEditMap.put(bean.getGoodsId(),holder.rlEdit);
        TextWatcher whatch=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) {
                //检查用户输入是否合法,进行相应处理
                checkUserInfoIsIllegal(holder,input,minNum,position);
            }
        };
        //添加监听
        holder.mEtNum.addTextChangedListener(whatch);
    }
/**获取输入值
     * 
     *作用 检查用户输入信息是否合法
     */
    private void checkUserInfoIsIllegal(final MyViewHolder holder, final String finalInput, final String finalMinNum, final int position) {
        //延迟1s秒处理结果
        //获取该商品Id对应的控件,方便下面进行显示隐藏
        holder.rlEdit= (RelativeLayout) rlEditMap.get(lists.get(position).getGoodsId());
        holder.mEtNum= (EditText) mEtNumMap.get(lists.get(position).getGoodsId());
        holder.mTvHint= (TextView) mTvHintMap.get(lists.get(position).getGoodsId());
        //下面是伪代码,具体实现根据具体的业务逻辑需求实现
          if(满足输入条件){
                holder.rlEdit,holder.mEtNum,holder.mTvHint 正常展示
        }ese{
              holder.rlEdit,holder.mEtNum,holder.mTvHint 非正常展示
       }
      //这样就避免了刷新带来的问题
      
    }

总结

1:map中记录用户编辑数量的对应关系key使用的是goodId,最开始其实使用的是item的position,但是商品可以删除增加,使用position和编辑数量进行对应,是不安全的。最好选择不变的id或者其他不变唯一属性的作为key;
2:recycleView中禁止复用性(holder.setIsRecyclable(false);)当列表书数量不多的时候,可以考虑使用,当数量比较多的时候,不建议使用,禁用复用性,就失去了recycleView的价值;
3:这篇文章主要点:就是利用HashMap中key和value的一一对应关系,去解决RecycleView刷新中,遇到的数据错乱问题以及控件显示问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容