EditText在滚动后丢失的内容RecyclerView

问题描述:

我有一个问题,我几个星期都无法解决。我有一个应用程序添加两个EditTexts和一个CheckBox按钮单击。但是,只要我在EditTexts中键入一些内容,然后向下滚动,当我向后滚动时,内容就会消失。我无法弄清楚这个问题的解决方法。我发现了其他一些非常类似的帖子,但是我已经尝试了所有可以找到的解决方案,但没有一个似乎对我有用。这里有几个类似的帖子,我发现:EditText在滚动后丢失的内容RecyclerView

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

此外,在另一个说明中,我已经启用了应用程序拖放和刷卡解散。因此,如果您有解决方案,请考虑这一点。谢谢!

MainActivity
import android.content.ClipData; 
import android.support.v7.app.AlertDialog; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.helper.ItemTouchHelper; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ListView; 
import android.widget.RelativeLayout; 
import android.widget.Toast; 

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

public class MainActivity extends AppCompatActivity { 

    private ArrayList<ListItems> itemsList; 
    private RecyclerView mRecyclerView; 
    private MyRecyclerAdapter adapter; 
    private List<String> courseStrings = new ArrayList<>(); 
    private List<String> creditStrings = new ArrayList<>(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     courseStrings.add(""); 
     creditStrings.add(""); 

     // Toast variable in order to fix toast queueing issue. 
     final Toast toast = Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT); 

     // For the recycler view. 
     mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); 

     itemsList = new ArrayList<>(); 
     adapter = new MyRecyclerAdapter(MainActivity.this, itemsList, courseStrings, creditStrings); 
     mRecyclerView.setAdapter(adapter); 
     mRecyclerView.setLayoutManager(linearLayoutManager); 

     // For the addCourse button. 
     final Button addCourse = (Button) findViewById(R.id.addCourse); 
     addCourse.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       adapter.createListItem(new ListItems(null, null, false), toast); 
       toast.setText("New course added"); 
       toast.show(); 
      } 
     }); 

     final Button clearAll = (Button) findViewById(R.id.clearAll); 
     clearAll.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       // In order to clear the list. 
       if (itemsList.size() == 0) { 
        toast.setText("All courses have already been cleared."); 
        toast.show(); 
       } else { 
        adapter.clearAdapter(); 
        toast.setText("All courses have been cleared."); 
        toast.show(); 
       } 
      } 
     }); 

     // For the drag and drop/swipe to dismiss. 
     ItemTouchHelper itemTouchHelper = new ItemTouchHelper(
       new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 
         ItemTouchHelper.LEFT) { 
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
         final int fromPos = viewHolder.getAdapterPosition(); 
         final int toPos = target.getAdapterPosition(); 
         Collections.swap(itemsList, fromPos, toPos); 
         adapter.notifyItemMoved(fromPos, toPos); 
         return true; 
        } 
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 
         adapter.onItemDismiss(viewHolder.getAdapterPosition()); 
        } 
       }); 
     itemTouchHelper.attachToRecyclerView(mRecyclerView); 
    } // End of onCreate 
} // End of MainActivity 

MyRecyclerAdapter
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 

listItems中
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 

new_course_row.xml
<?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> 

activity_main.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> 

预先感谢您的帮助!我真的可以使用一个解决方案!

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

编辑x2:有没有在这一段时间工作,并没有得到任何答案。甚至为这篇文章获得了“风滚草”徽章!有人有主意吗?

虽然我不太确定,但我相信这是因为回收商视图重新生成它的位置。对于您的自定义编辑文本,您将添加字符串'@Override public void onTextChanged(CharSequence s,int start,int before,int count){s}; courseStrings.add(s.toString()); }

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

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

holder.courseText.setTag(position); 

in onBindViewHolder()。 单独尝试使用两种文本。如果确实有效,请尝试使用

holder.view.setTag(position);