RecyclerView采坑记录

mac2024-08-16  67

今天使用RecyclerView过程中遇到了坑,RecyclerView的条目中既有checkbox,又有edittext,然后将数据展示上去一点问题也没有,很美观,然而点击checkbox选中的时候,会发现其他条目中也有被选中的,原因在于我们在onBindViewHolder方法中使用viewhodler对条目进行复用,然后导致出现了问题。

找了一些解决方法,说是将RecyclerView设置为不复用,但是这种方式会影响到程序性能,数据多的时候,还会影响到稳定性,不推荐使用该方法。

另一种方式,在onBindViewHolder中设置checkbox的状态变化的监听,在状态发生变化时,将状态设置给我们的bean对象,然后在onBindViewHolder方法上方根据bean对象的选中状态,对viewHolder中的状态进行设置,并在设置状态变化的监听前,取消掉状态监听。如下:

// 先对复用控件设置选中状态 viewHolder.checkBox.setChecked(deviceValueBean.getIsChecked()); // 取消状态变化的监听 viewHolder.checkBox.setOnCheckedChangeListener(null); // 重新设置状态变化监听 viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (cbChangedListener != null) { cbChangedListener.OnItemCBChangedListener(position, isChecked); } mDeviceValueBeanList.get(position).setIsChecked(isChecked); } });

通过以上方法,checkbox的数据串台问题解决了,但是还有edittext的串台问题,其实解决思路大致是一样的,还是先给edittext设置内容,再取消焦点变化的监听,然后设置焦点发生变化的监听,在该监听中获取焦点设置textwatcher,失去焦点取消textwatcher,在afterTextChanged方法中对bean对象的输入内容字段重新赋值。

viewHolder.edtDeviceValue.setOnFocusChangeListener(null); viewHolder.edtDeviceValue.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { viewHolder.edtDeviceValue.addTextChangedListener(textWatcher); } else { viewHolder.edtDeviceValue.removeTextChangedListener(textWatcher); } } }); final TextWatcher textWatcher = 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) { DeviceValueBean deviceValueBean1 = mDeviceValueBeanList.get(position); deviceValueBean1.setInputContent(inputString); } }; 然后根据有无输入内容,重新设置edittext的内容 if (TextUtils.isEmpty(deviceValueBean.getInputContent())) { viewHolder.edtDeviceValue.setText(""); if (!TextUtils.isEmpty(minValue) && !TextUtils.isEmpty(maxValue)) { String hint = "(" + minValue + " - " + maxValue + ")"; viewHolder.edtDeviceValue.setHint(hint); } else { viewHolder.edtDeviceValue.setHint(deviceValueBean.getTip()); } } else { viewHolder.edtDeviceValue.setText(deviceValueBean.getInputContent()); }

这里面,我刚开始只给edittext设置了hint内容,所以一直没发现这块的问题,在内容不为空的时候需要设置内容,为空的时候如有要设置hint内容,也需要调用setText()方法设置一个空字符串。

在edittext和checkbox的监听器中需要根据position重新获取bean对象,然后再对bean对象重新赋值才有效。

还有要看自己写的viewholder中的字段,每一个字段都需要设置相应的内容,内容不会变化的,直接设置,内容变化的,需要按照edittext和checkbox的方式进行动态设置。

最新回复(0)