我在 RecyclerView
中有一个 EditText
。当我编辑 EditText
的内容并向上/向下滚动时,相同的内容会显示在另一行中。
另外,如果我返回到相同的位置,则 EditText
为空。
以下是 RecyclerView
的每个项目的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#F3F2F2"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="@+id/txt_jantri_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/quicksand_bold"
android:text="1"
android:textColor="@color/theme_color"
android:textSize="10sp" />
<EditText
android:id="@+id/ed_jantri_number"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:background="@drawable/shape_jantri_edittext"
android:fontFamily="@font/quicksand_bold"
android:gravity="center"
android:inputType="number"
android:maxLines="1"
android:minLines="1"
android:padding="5dp"
android:textSize="12dp" />
</LinearLayout>
</LinearLayout>
这是适配器类,我将文本设置为框编号:
public class AdapterJantri extends RecyclerView.Adapter<AdapterJantri.Myholder> {
@NonNull
@Override
public Myholder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new Myholder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_jantri_view, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull Myholder myholder, int i) {
myholder.txtJantriNumber.setText(String.valueOf(i + 1));
}
@Override
public int getItemCount() {
return 99;
}
public class Myholder extends RecyclerView.ViewHolder {
EditText edJantriNumber;
TextView txtJantriNumber;
public Myholder(@NonNull View itemView) {
super(itemView);
edJantriNumber = itemView.findViewById(R.id.ed_jantri_number);
txtJantriNumber = itemView.findViewById(R.id.txt_jantri_number);
}
}
}
这是 Activity
public class JantriActivity extends AppCompatActivity {
RecyclerView recyclerView;
SlideToActView slideToActView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jantri);
initiliaization();
recyclerView.setAdapter(new AdapterJantri());
}
private void initiliaization() {
recyclerView = findViewById(R.id.recycler_jantri);
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
slideToActView = findViewById(R.id.swipe_save_transaction);
}
}
最佳答案
ViewAdapter
重用View
。因此,当滚动时,适配器将重新使用不再可见的 View ,而不是创建新 View 。
所以,这就是您拥有 onBindViewHolder
的主要原因。通过这种方法,Android 让您有机会在 View 内容变得可见之前更新它。如果您不更新(TextView
和 EditText
)的所有内容,您会发现类似您提到的问题。
注意这段代码:
@Override
public void onBindViewHolder(@NonNull Myholder myholder, int i) {
myholder.txtJantriNumber.setText(String.valueOf(i + 1));
}
如您所见,您仅更新了 TextView
。因此,TextView
(无论是否重复使用)将始终显示正确的文本。但是,您并未更新 EditText
的内容。这样,如果 View 刚刚创建,则 EditText
为空。如果 View 被重新使用,您将看到旧值(来自不同的行)。
因此,为了保持正确更新 EditText
,您必须将所有文本存储在单独的列表中。例如:
public class AdapterJantri extends RecyclerView.Adapter<AdapterJantri.Myholder> {
private String[] mTextList;
public AdapterJantri() {
mTextList = new String[getItemCount()];
}
@Override
public void onBindViewHolder(@NonNull Myholder myholder, int i) {
myholder.txtJantriNumber.setText(String.valueOf(i + 1));
// Here, you update the EditText content
myholder.edJantriNumber.setText(mTextList[i]);
}
@Override
public void onViewRecycled(@NonNull final Myholder holder) {
// Here, you save the text before the view gets recycled
int index = holder.getAdapterPosition();
if (index >= 0) {
mTextList[index] = holder.edJantriNumber.getText().toString();
}
}
}
编辑
如果您有 TextWatcher
并且需要暂时禁用它,我建议:
第一
不要在bindViewHolder
内创建TextWatcher
。您不需要每次都创建一个新的。只需添加它并删除它。您可以使用自己的 MyHolder
作为 TextWatcher
public class Myholder extends RecyclerView.ViewHolder implements TextWatcher {
EditText edJantriNumber;
TextView txtJantriNumber;
public Myholder(@NonNull View itemView) {
super(itemView);
edJantriNumber = itemView.findViewById(R.id.ed_jantri_number);
txtJantriNumber = itemView.findViewById(R.id.txt_jantri_number);
}
@Override
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
// Add your code here
}
@Override
public void onTextChanged(final CharSequence s, final int start, final int before,
final int count) {
// Add your code here
}
@Override
public void afterTextChanged(final Editable s) {
// Add your code here
}
public void disableTextChangeListner() {
// This will remove the listener. So, it will stop to listen to new events
edJantriNumber.removeTextChangedListener(this);
}
public void addTextChangeListner() {
// This will add the listener. So, it will start to listen to new events
edJantriNumber.addTextChangedListener(this);
}
}
然后,在bindViewHolder
期间,禁用监听器,设置新文本,然后再次添加监听器,如下所示:
@Override
public void onBindViewHolder(@NonNull Myholder myholder, int i) {
myholder.disableTextChangeListner();
myholder.txtJantriNumber.setText(String.valueOf(i + 1));
myholder.edJantriNumber.setText(mTextList[i]);
myholder.addTextChangeListner();
}
关于android - EditText 在 RecyclerView 上丢失其内容。如何恢复其内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56261881/