在RecyclerView中滚动后,EditText丢失内容

时间:2016-06-12 21:03:06

标签: java android android-edittext android-recyclerview

我遇到了一个问题,我现在几周都无法解决。我有一个应用程序,在按钮单击时添加两个EditTexts和一个CheckBox。但是,每当我在EditTexts中键入一些内容,然后向下滚动时,当我向上滚动时内容就会消失。我无法弄清楚这个问题。我找到了一些非常相似的帖子,但是我已经尝试了所有我能找到的解决方案,但似乎没有人能为我做这个伎俩。以下是我发现的几个类似帖子:

我最近对我的程序做了一些更改,试图解决这个问题。我在我的MainActivity中添加了一个ArrayList并将其传递给我的适配器。我还制作了两个自定义文本侦听器,其中onTextChanged,我将字符串添加到ArrayList。然后,在onBindViewHolder中,我更新文本侦听器中的位置,然后将文本设置为该位置的ArrayList中的String。但是,这会给出一些奇怪的错误。现在,当我向EditText添加内容并向下滚动时,它会将其添加到多个EditTexts,甚至更改其中一些内容。我不知道如何解决这个问题。

另外,在另一个注释中,我启用了拖放功能,然后滑动即可关闭。因此,如果您有解决方案,请考虑到这一点。谢谢!

MainActivity

import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.view.LayoutInflater;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.CustomRowViewHolder> {

     private ArrayList<ListItems> itemsList;
     private Context mContext;
     private List<String> courseStrings;
     private List<String> creditStrings;


    public MyRecyclerAdapter(Context context, ArrayList<ListItems> itemsList, List<String> courseStrings, List<String> creditStrings){
        this.itemsList = itemsList;
        this.mContext = context;
        this.courseStrings = courseStrings;
        this.creditStrings = creditStrings;
    }

     @Override
     public MyRecyclerAdapter.CustomRowViewHolder onCreateViewHolder(final ViewGroup viewGroup, int position) {
         View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.new_course_row, null);
         final CustomRowViewHolder holder = new CustomRowViewHolder(v, new CoursesCustomTextListener(), new CreditsCustomTextListener());
         holder.creditsText.setInputType(InputType.TYPE_CLASS_NUMBER);
         holder.checkBox.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 if(holder.checkBox.isChecked()) {
                     holder.courseText.setEnabled(false);
                     holder.courseText.setFocusable(false);
                     holder.courseText.setInputType(InputType.TYPE_NULL);
                     holder.creditsText.setEnabled(false);
                     holder.creditsText.setFocusable(false);
                     holder.creditsText.setInputType(InputType.TYPE_NULL);
                 } else {
                     holder.courseText.setEnabled(true);
                     holder.courseText.setFocusable(true);
                     holder.courseText.setFocusableInTouchMode(true);
                     holder.courseText.setInputType(InputType.TYPE_CLASS_TEXT);
                     holder.creditsText.setEnabled(true);
                     holder.creditsText.setFocusable(true);
                     holder.creditsText.setFocusableInTouchMode(true);
                     holder.creditsText.setInputType(InputType.TYPE_CLASS_NUMBER);
                 } // End if else
             }
         });
         return holder;
     } // End of onCreateViewHolder

     @Override
     public void onBindViewHolder(CustomRowViewHolder holder, final int position) {
         ListItems listItem = itemsList.get(position);
         int focusedItem = 0;
         holder.itemView.setSelected(focusedItem == position);
         holder.getLayoutPosition();

         holder.creditsCustomTextListener.updatePosition(position);
         holder.creditsCustomTextListener.updatePosition(position);

         holder.courseText.setText(courseStrings.get(position));
         holder.creditsText.setText(creditStrings.get(position));

         // Set listener to check box.
         holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
             @Override
             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                 itemsList.get(position).setIsComplete(b);
             }
         });
         holder.checkBox.setChecked(  itemsList.get(position).getIsComplete());
     } // End of onBindViewHolder

     public void clearAdapter() {
         itemsList.clear();
         notifyDataSetChanged();
     } // End of clearAdapter

     public int getItemCount() {
         return(null != itemsList ? itemsList.size() : 0);
     } // End of getItemCount

     public void onItemDismiss(int position) {
         itemsList.remove(position);
         notifyItemRemoved(position);
         notifyItemRangeChanged(position, itemsList.size());
     } // End of onItemDismiss

     public void createListItem(ListItems listItem, Toast toast) {
         itemsList.add(listItem);
         int position = itemsList.indexOf(listItem);
         notifyItemInserted(position);
     } // End of createListItem

     ///////////////////////////////////// CustomRowViewHolder /////////////////////////////////////

     public static class CustomRowViewHolder extends RecyclerView.ViewHolder {

         public EditText courseText;
         public EditText creditsText;
         public CheckBox checkBox;
         public RelativeLayout relativeLayout;
         public CoursesCustomTextListener coursesCustomTextListener;
         public CreditsCustomTextListener creditsCustomTextListener;

         public CustomRowViewHolder(View view, CoursesCustomTextListener coursesCustomTextListener, CreditsCustomTextListener creditsCustomTextListener) {
             super(view);
             this.coursesCustomTextListener = coursesCustomTextListener;
             this.creditsCustomTextListener = creditsCustomTextListener;
             this.courseText = (EditText) view.findViewById(R.id.course);
             this.creditsText = (EditText) view.findViewById(R.id.credits);
             this.checkBox = (CheckBox) view.findViewById(R.id.complete);
             this.relativeLayout = (RelativeLayout) view.findViewById(R.id.relLayout);
             this.courseText.addTextChangedListener(coursesCustomTextListener);
             this.creditsText.addTextChangedListener(creditsCustomTextListener);
         }
     }

     ////////////////////////////////// CoursesCustomTextListener //////////////////////////////////

     private class CoursesCustomTextListener implements TextWatcher {
         private int position;

         public void updatePosition(int position) {
             this.position = position;
         }
         @Override
         public void beforeTextChanged(CharSequence s, int start, int count, int after) {
             // No operation to perform.
         }

         @Override
         public void onTextChanged(CharSequence s, int start, int before, int count) {
             courseStrings.add(s.toString());
         }

         @Override
         public void afterTextChanged(Editable s) {
             // No operation to perform.
         }
     }

     ////////////////////////////////// CreditsCustomTextListener //////////////////////////////////

     private class CreditsCustomTextListener implements TextWatcher {
         private int position;

         public void updatePosition(int position) {
             this.position = position;
         }
         @Override
         public void beforeTextChanged(CharSequence s, int start, int count, int after) {
             // No operation to perform.
         }

         @Override
         public void onTextChanged(CharSequence s, int start, int before, int count) {
             creditStrings.add(s.toString());
         }

         @Override
         public void afterTextChanged(Editable s) {
             // No operation to perform.
         }
     }
} // End of MyRecyclerAdapter

MyRecyclerAdapter

import java.util.ArrayList;

public class ListItems {
    private String course;
    private String credits;
    private Boolean complete;

    public ListItems(String mCourse, String mCredits, Boolean mComplete) {
        course = mCourse;
        credits = mCredits;
        complete = mComplete;
    }

    public String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public String getCredits() {
        return credits;
    }

    public void setCredits(String credits) {
        this.credits = credits;
    }

    public Boolean getIsComplete() {
        return complete;
    }

    public void setIsComplete(Boolean complete) {
        this.complete = complete;
    }
} // End of ListItems

listItems中

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/relLayout"
    android:layout_margin="5dp">

    <EditText
        android:layout_width="130dp"
        android:layout_height="wrap_content"
        android:id="@+id/course"
        android:hint="Enter Course ID"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:textSize="16sp"
        android:maxLines="1" />

    <EditText
        android:layout_width="115dp"
        android:layout_height="wrap_content"
        android:id="@+id/credits"
        android:hint="Enter Credits"
        android:layout_alignBottom="@+id/course"
        android:textSize="16sp"
        android:layout_toRightOf="@+id/course"
        android:maxLines="1" />

    <CheckBox
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Check if complete"
        android:id="@+id/complete"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_alignBottom="@+id/course"
        android:textSize="13sp"
        android:paddingBottom="4dp"
        android:paddingTop="4dp" />

</RelativeLayout>

new_course_row.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingRight="10dp"
    android:paddingLeft="10dp"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:id="@+id/rl"
    tools:context=".MainActivity" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Add Course"
        android:id="@+id/addCourse"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:textColor="#FFF"
        android:background="@drawable/my_button"
        android:textSize="18dp"
        android:paddingRight="5dp"
        android:paddingLeft="5dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Clear All"
        android:id="@+id/clearAll"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:textColor="#FFF"
        android:background="@drawable/my_button"
        android:textSize="18dp"
        android:paddingRight="5dp"
        android:paddingLeft="5dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"/>

    <android.support.v7.widget.RecyclerView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/recycler_view"
        android:layout_below="@+id/addCourse"
        android:layout_marginTop="10dp"
        />
</RelativeLayout>

activity_main.xml中

{{1}}

提前感谢您的帮助!我真的可以使用解决方案!

编辑:我现在已经注意到了,比如说我在第一个EditText中输入“aaaaaaa”,然后它会在列表的下方向EditText添加“a”,然后在那个之后将“aa”添加到EditText,然后“aaa”,“aaaa”,直到达到“aaaaaaa”。然后会有一些空的EditText,然后它会重新开始。这是一个视觉:Here

编辑x2:有一段时间没有处理过这个问题,并且没有得到任何答案。甚至为这篇文章获得了“Tumbleweed”徽章!有人有什么想法吗?

1 个答案:

答案 0 :(得分:1)

虽然我不太确定,但我相信这种情况正在发生,因为回收者的观点重新产生了它的位置。对于自定义编辑文本,您要添加字符串`@Override          public void onTextChanged(CharSequence s,int start,int before,int count){              courseStrings.add(s.toString());          }

两个编辑文本。   在recyler视图中,您已实现this.courseText.addTextChangedListener(coursesCustomTextListener);

所以每次滚动时都会调用onBind方法,并且当位置发生变化时,也必须调用它。因此它必须再生。我请你先试试

holder.courseText.setTag(position); 

在onBindViewHolder()中。 单独尝试两种文本。如果它确实有效,请尝试

holder.view.setTag(position);