如何阻止RecyclerView滚动时重置EditText内容?
解决RecyclerView中EditText/TextView内容重置的问题
我太懂这种滚动一下输入内容就消失的烦躁了!RecyclerView的视图复用机制虽然高效,但确实容易让新手踩这个坑——你试过的getItemViewType()其实是用来区分不同布局类型的item的,和你遇到的数据丢失问题无关,咱们换个思路来解决:
核心思路:让数据源成为唯一的数据来源
RecyclerView的视图是会被复用的,所以不能依赖视图本身存储数据,必须把每个item的状态(EditText内容、TextView文本)都存在一个独立的数据源里,视图只是这个数据源的“展示窗口”。
步骤1:创建数据类保存每个item的状态
先定义一个类,用来存储单个列表项的所有需要保留的数据:
// Kotlin示例 data class ListItem( var editTextContent: String = "", var textViewText: String = "默认文本" // 替换成你的TextView初始内容 )
// Java示例 public class ListItem { private String editTextContent; private String textViewText; public ListItem() { this.editTextContent = ""; this.textViewText = "默认文本"; } // 别忘了添加getter和setter方法 public String getEditTextContent() { return editTextContent; } public void setEditTextContent(String editTextContent) { this.editTextContent = editTextContent; } public String getTextViewText() { return textViewText; } public void setTextViewText(String textViewText) { this.textViewText = textViewText; } }
步骤2:在Adapter中维护数据源并实时同步
你的Adapter要持有这个List<ListItem>类型的数据源,在绑定视图时从数据源取数据展示,同时监听EditText的输入变化,实时把内容同步回数据源:
// Kotlin示例 class MyAdapter(private val itemList: MutableList<ListItem>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() { inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val editText: EditText = itemView.findViewById(R.id.your_edit_text_id) val textView: TextView = itemView.findViewById(R.id.your_text_view_id) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.your_item_layout, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val currentItem = itemList[position] // 先移除之前的监听!避免复用视图时重复触发数据混乱 holder.editText.removeTextChangedListener(holder.textWatcher) // 从数据源加载最新数据到视图 holder.editText.setText(currentItem.editTextContent) holder.textView.text = currentItem.textViewText // 添加新的文本监听,实时同步输入内容到数据源 holder.editText.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { currentItem.editTextContent = s.toString() } }) } override fun getItemCount() = itemList.size }
关键注意点:
- 一定要先移除EditText的旧监听再设置新内容,不然复用视图时会出现数据串位的情况
- 所有修改操作(比如更新TextView文本)都要先修改数据源,再调用
notifyItemChanged(position)来刷新视图,而不是直接修改TextView
为什么getItemViewType()没用?
这个方法的作用是告诉RecyclerView当前item属于哪种布局类型,方便它复用对应类型的视图。你的问题是同类型item的数据丢失,和布局类型无关,所以这个方法解决不了你的问题。
内容的提问来源于stack exchange,提问作者Achmad Naufal Syafiq
相关产品推荐
相关产品推荐

