You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套RecyclerView修改单个EditText时其余选项值变为null如何解决

问题原因

你的代码逻辑存在两个核心错误,直接导致其他选项被置为null:

  1. 旧值拷贝逻辑完全失效:你先创建了全为null的新数组arrayOfNulls(questionOptionAddList.size),后续循环中使用?.安全调用给新数组元素的text属性赋值——但新数组所有位置初始都是null,这行代码会直接跳过所有赋值操作,根本没有把旧数组的选项拷贝到新数组里,最后你只给当前输入的位置塞了新创建的选项对象,其余位置自然保持null值。
  2. 位置取值不可靠:使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:06:16