There was a requirement in a recent project that the quantities in the shopping cart list could be manually modified by input. Judging by the requirements, the shopping cart is a list containing Edittext. Then the problem comes. Recyclerview contains the problem of data chaos when EditText scrolls. The data chaos is caused by the reuse of RecyclerView. Several approaches to this problem have been documented.
Note: Demo cited BaseRecyclerViewAdapteHelper, therefore inherited BaseQuickAdapter adapter, This annotation is to prevent does not understand the convert (BaseViewHolder helper, EdittextInRecyclerViewOfBean item) this method
Method one: mandatory discontinuation of Recyclerview reuse.
This method is not recommended. One of the biggest benefits of recyclerView is reuse. If reuse is stopped, it will take up a lot of memory when there is a large amount of data or a large figure in the items, which will cause lag or crash.
helper.setIsRecyclable(false);
Copy the code
Method 2: Add or remove the Edittext TextChangedListener by listening on focus
Data malfunctions are handled in onBindViewHolder() by adding or removing the Edittext TextChangedListener at the appropriate time. The appropriate timing is to add listeners when Edittext gains focus and remove them when it loses focus to ensure that the data is correct.
@Override
protected void convert(BaseViewHolder helper, EdittextInRecyclerViewOfBean item) {
EditText editText = helper.getView(R.id.et);
editText.setText(item.getNum() + "");
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) {// Data is processed hereif (TextUtils.isEmpty(s.toString())) {
item.setNum(0);
} else{ item.setNum(Integer.parseInt(s.toString())); }}}; editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus){
editText.addTextChangedListener(textWatcher);
}else{ editText.removeTextChangedListener(textWatcher); }}}); }Copy the code
View setTag(
The TextWatcher listener is removed before each fill, then the data is filled for the EditText, and finally the TextWatcher listener is added for the EditText.
@Override
protected void convert(BaseViewHolder helper, EdittextInRecyclerViewOfBean item) {
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) {
if (TextUtils.isEmpty(s.toString())) {
item.setNum(0);
} else{ item.setNum(Integer.parseInt(s.toString())); }}}; EditText editText = helper.getView(R.id.et); // To avoid TextWatcher being called when settext () is called, remove it earlyif (editText.getTag() instanceof TextWatcher) {
editText.removeTextChangedListener((TextWatcher) editText.getTag());
}
editText.setText(item.getNum() + ""); / / to add TextWatcher listening editText. AddTextChangedListener (TextWatcher); // Bind TextWatcher to EditText edittext.settag (TextWatcher); }Copy the code
Method 4: Bind position for each EditText
When the EditText on the corresponding position changes, the corresponding TextWatcher listens and modifies the corresponding position’s data
public class EditTextInRecyclerViewAdapter extends RecyclerView.Adapter {
private List<EdittextInRecyclerViewOfBean> mList = new ArrayList<>();
public void setData(List<EdittextInRecyclerViewOfBean> list) {
this.mList = list;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_edittext, parent, false);
return new ViewHolder(v, new ITextWatcher());
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ViewHolder viewHolder = (ViewHolder) holder;
viewHolder.mITextWatcher.bindPosition(position);
viewHolder.mEditText.setText(mList.get(position).getNum()+"");
}
@Override
public int getItemCount() {
return mList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
EditText mEditText;
ITextWatcher mITextWatcher;
private ViewHolder(View v, ITextWatcher watcher) {
super(v);
this.mEditText = v.findViewById(R.id.et);
this.mITextWatcher = watcher;
this.mEditText.addTextChangedListener(watcher);
}
}
class ITextWatcher implements TextWatcher {
private int position;
private void bindPosition(int position) {
this.position = position;
}
@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.isEmpty(s.toString())) {
mList.get(position).setNum(0);
} else{ mList.get(position).setNum(Integer.parseInt(s.toString())); }}}}Copy the code