处理RecyclerView中嵌套EditText数据显示混乱

在平常开发中 RecyclerView 我们是常用到的,因为它的回收复用机制会遇到过很多坑,比如嵌套 CheckBox 、RadioButton 、 EditText 等组件在滑动时会出现数据混乱问题。今天我们就来使用 EditText 写一个例子来处理这个问题吧。
private void initRecyclerView() {
    RecyclerView mRecyclerView = findViewById(R.id.rv_simple);

    SimpleAdapter simpleAdapter = new SimpleAdapter();
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);

    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(layoutManager);
    mRecyclerView.setAdapter(simpleAdapter);
}

private class SimpleAdapter extends RecyclerView.Adapter {

    /**
     * 显示条数
     */
    private final int mSimpleNum = 20;
    /**
     * ViewHolder 创建次数
     */
    private int mCreateTimes = 0;
    /**
     * ViewHolder 绑定次数
     */
    private int mBindTimes = 0;
    /**
     * 已经绑定文本变化监听器
     */
    private final boolean mBoundWatcher = true;
    /**
     * 输入框文本缓存
     */
    private SparseArray<String> mTextCache = new SparseArray<>();

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_simpe, parent, false);
        Log.i("onCreateViewHolder", "CreateTimes == " + mCreateTimes++);
        return new SimpleHolder(view);
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        Log.i("onBindViewHolder", "BindTimes == " + mBindTimes++ + " Position == " + holder.getAdapterPosition());
           
        Log.i("TEXT_SHOW", "ShowPosition == " + holder.getAdapterPosition());
        ((SimpleHolder) holder).mEtSimple.setText(mTextCache.get(holder.getAdapterPosition()), "");
          
        // 如果已经绑定文本变化监听器不再次绑定
        if (((SimpleHolder) holder).mEtSimple.getTag() != null && (boolean) ((SimpleHolder) holder).mEtSimple.getTag()) {
            return;
        }
        ((SimpleHolder) holder).mEtSimple.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                // 如果填入数据与缓存数据相同返回
                if (TextUtils.equals(mTextCache.get(holder.getAdapterPosition()), s.toString())) {
                    return;
                }
                mTextCache.put(holder.getAdapterPosition(), s.toString());
                Log.i("TEXT_PUT", "PutPosition == " + holder.getAdapterPosition());
            }
        });
        ((SimpleHolder) holder).mEtSimple.setTag(mBoundWatcher);
        }

    @Override
    public int getItemCount() {
        return mSimpleNum;
    }

    class SimpleHolder extends RecyclerView.ViewHolder {

        EditText mEtSimple;

        SimpleHolder(View itemView) {
            super(itemView);
            mEtSimple = itemView.findViewById(R.id.et_simple);
        }
    }
 }
处理混乱的重点其实就是在数据输入以后进行保存,每次进行手动赋值。

注意:
1.处理 Key 一定为 int 类型的数据时使用 Sparse*** 之类的数据结构可以节省内存。
2.对于添加过文本变化监听器的 EditText 使用 Tag 进行区分,不要每次都进行 addTextChangedListener 。
3.由于我添加监听时使用的是匿名内部类,所以获取 position 时候使用的为 holder.getAdapterPosition() (或者使用 holder.getLayoutPosition()),这是必要的,否则当 position 变为 final 会出现新的问题。


final int position 导致问题.png
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值