I have a RecyclerView that has many cards that hold 4 EditText. When I input values in one EditText of one card, it fills the same value in random cards. Surprisingly it does not jump EditTexts for example:
If I input values in edittext1 of card1 it would fill the same value into edittext1 in card8 and if I change the value in card8 it will change the value back in card1. Could someone please tell me why this is happening.
Thank You in Advance
Here is my code:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String[] mDataset;
public String[][] data = new String[30][4];
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public LinearLayout mCardView;
public ViewHolder(LinearLayout v) {
super(v);
mCardView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
LinearLayout v = (LinearLayout) LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final EditText txt = (EditText) holder.mCardView.findViewById(R.id.ip1_text);
final EditText txt2 = (EditText) holder.mCardView.findViewById(R.id.ip2_text);
final EditText txt3 = (EditText) holder.mCardView.findViewById(R.id.ip3_text);
final EditText txt4 = (EditText) holder.mCardView.findViewById(R.id.ip4_text);
txt.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) {
data[position][0] = s.toString();
Log.d("DATA" + position + "0", s.toString());
}
});
txt2.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) {
data[position][1] = s.toString();
Log.d("DATA" + position + "1", s.toString());
}
});
txt3.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) {
data[position][2] = s.toString();
Log.d("DATA" + position + "2", s.toString());
}
});
txt4.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) {
data[position][3] = s.toString();
Log.d("DATA" + position + "3", s.toString());
}
});
TextView t = (TextView) holder.mCardView.findViewById(R.id.serNo);
t.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length;
}
public String[][] getData() {
return data;
}
And this is my card xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1">
<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
android:id="@+id/card_view"
android:layout_width="375dp"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:backgroundTint="#eeeeee"
card_view:cardCornerRadius="4dp">
<TextView
android:id="@+id/serNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="number"
android:layout_margin="20dp"
android:textColor="@color/cardview_dark_background" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<EditText
android:id="@+id/ip1_text"
android:layout_width="100dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:layout_marginTop="20dp"
android:background="@color/cardview_light_background"
android:inputType="number"
android:maxLength="2" />
<EditText
android:id="@+id/ip3_text"
android:layout_width="80dp"
android:layout_height="30dp"
android:layout_below="@+id/ip1_text"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:background="@color/cardview_light_background"
android:inputType="number"
android:maxLength="1" />
<EditText
android:id="@+id/ip2_text"
android:layout_width="100dp"
android:layout_height="30dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_toRightOf="@+id/ip1_text"
android:background="@color/cardview_light_background"
android:inputType="number"
android:maxLength="2" />
<EditText
android:id="@+id/ip4_text"
android:layout_width="80dp"
android:layout_height="30dp"
android:layout_below="@+id/ip2_text"
android:layout_marginBottom="10dp"
android:layout_marginLeft="40dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@+id/ip3_text"
android:background="@color/cardview_light_background"
android:inputType="number"
android:maxLength="1" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>


That happens because the views inside a RecyclerView are being recycled. Inside the onBindViewHolder you need to set the specific texts to the EditTexts at the specific position.
Initialize your Views inside the ViewHolder and add the TextWatchers there as the whole philosophy of the RecyclerView is to reuse the views :
public static class ViewHolder extends RecyclerView.ViewHolder {
EditText txt;
EditText txt2;
EditText txt3;
EditText txt4;
TextView serNoTxt;
public ViewHolder(LinearLayout mCardView) {
super(mCardView);
txt = (EditText) mCardView.findViewById(R.id.ip1_text);
txt2 = (EditText) mCardView.findViewById(R.id.ip2_text);
txt3 = (EditText) mCardView.findViewById(R.id.ip3_text);
txt4 = (EditText) mCardView.findViewById(R.id.ip4_text);
setNoTxt = (TextView) mCardView.findViewById(R.id.serNo);
txt.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) {
data[getAdapterPosition()][0] = s.toString();
Log.d("DATA" + getAdapterPosition() + "0", s.toString());
}
});
txt2.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) {
data[getAdapterPosition()][1] = s.toString();
Log.d("DATA" + getAdapterPosition() + "1", s.toString());
}
});
txt3.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) {
data[getAdapterPosition()][2] = s.toString();
Log.d("DATA" + getAdapterPosition() + "2", s.toString());
}
});
txt4.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) {
data[getAdapterPosition()][3] = s.toString();
Log.d("DATA" + getAdapterPosition() + "3", s.toString());
}
});
}
}
Set the appropriate text to the EditTexts in the onBindViewHolder :
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.txt1.setText(data[position][0]);
holder.txt2.setText(data[position][1]);
holder.txt3.setText(data[position][2]);
holder.txt4.setText(data[position][3]);
holder.setNoTxt.setText(mDataset[position]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With