嵌套RecyclerView修改单个EditText时其余选项值变为null如何解决
问题原因
你的代码逻辑存在两个核心错误,直接导致其他选项被置为null:
- 旧值拷贝逻辑完全失效:你先创建了全为null的新数组
arrayOfNulls(questionOptionAddList.size),后续循环中使用?.安全调用给新数组元素的text属性赋值——但新数组所有位置初始都是null,这行代码会直接跳过所有赋值操作,根本没有把旧数组的选项拷贝到新数组里,最后你只给当前输入的位置塞了新创建的选项对象,其余位置自然保持null值。 - 位置取值不可靠:使用
holder.adapterPosition获取父列表位置存在风险,当ViewHolder复用时该值可能返回POSITION_NONE(值为-1),会触发数组越界异常。
从你打印的日志也能验证这个问题:每次回调后新数组永远只有当前正在输入的位置有值,其余位置全是null,就是因为旧值根本没拷贝成功。
修复方案
1. 修正回调内的数组更新逻辑
不要新建全null数组再做无效赋值,直接基于旧数组拷贝后更新对应位置的值即可,参考实现:
// 注意:回调接口需要新增父项位置参数,不要在回调内部靠holder取位置 override fun onOptionTextChanged(parentPosition: Int, optionPosition: Int, text: String) { val targetQuestion = questions[parentPosition] // 直接拷贝旧数组的所有元素引用 val updatedOptions = targetQuestion.options.copyOf() // 更新当前输入位置的选项,保留原有其他字段的值 updatedOptions[optionPosition] = QuestionOptionAdd( text = text, hasImage = updatedOptions[optionPosition]?.hasImage ?: false, imageUrl = updatedOptions[optionPosition]?.imageUrl ?: "" ) // 替换为更新后的数组 targetQuestion.options = updatedOptions // 用payload做局部刷新,避免全局刷新导致EditText失焦 notifyItemChanged(parentPosition, "option_update") }
2. 补全嵌套RecyclerView的EditText适配逻辑
避免复用导致的回调错乱、输入中断问题:
- 子Adapter的
onBindViewHolder中,给EditText绑定TextWatcher前必须先移除之前绑定的旧Watcher,防止复用时触发其他位置的回调 - 子Adapter触发回调时,需要同时把当前绑定的父项位置、子项位置两个参数通过接口传出,不要在父Adapter中依赖ViewHolder取位置
- 文本变化时不要全量刷新整个RecyclerView,使用带payload的局部刷新,保留EditText的焦点和输入状态
内容的提问来源于stack exchange,提问作者Sambhav Khandelwal
相关产品推荐
相关产品推荐

