EditText在RecyclerView上丢失其内容。如何还原其内容?

时间:2019-05-22 17:11:09

标签: android android-recyclerview

我在EditText中有一个RecyclerView。当我编辑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>

这是Adapter类,我在其中将文本设置为框号:

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);
        }
    }
}

这是活动

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);
    }
}

1 个答案:

答案 0 :(得分:1)

Variable.set重用了ViewAdapter。因此,在滚动时,适配器将重新使用不再可见的视图,而不是创建新视图。 因此,这就是拥有View的主要原因。通过这种方法,Android使您有机会在视图内容可见之前对其进行更新。如果您不会更新(onBindViewHolderTextView)的所有内容,则会发现类似您提到的问题。

请注意以下代码:

EditText

如您所见,您仅在更新@Override public void onBindViewHolder(@NonNull Myholder myholder, int i) { myholder.txtJantriNumber.setText(String.valueOf(i + 1)); } 。因此,TextView(是否重复使用)将始终显示正确的文本。但是,您不是在更新TextView的内容。这样,如果仅创建了View,则EditText为空。如果视图被重新使用,您将看到旧值(从另一行开始)。

因此,为了保持正确更新EditText,必须将所有文本存储在单独的列表中。例如:

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(); } } } ,并且需要暂时禁用它,我建议:

第一

请勿在{{1​​}}内创建TextWatcher。您无需每次都创建一个新的。只需添加并删除它。您可以将自己的TextWatcher用作bindViewHolder

MyHolder

然后,在TextWatcher期间,禁用侦听器,设置新文本,然后再次将侦听器添加为foolows:

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);
    }
}