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

实现可动态添加EditText的无限RecyclerView问题求助

解决RecyclerView添加EditText不更新的问题

问题根源分析

  • RecyclerView未设置LayoutManager:RecyclerView必须指定布局管理器(如LinearLayoutManager)才能正确渲染列表项,你的代码和布局中都未配置这一关键属性。
  • 重复创建适配器:每次点击按钮都新建适配器并赋值给RecyclerView,不仅效率低下,还会导致列表状态丢失,正确做法是复用同一适配器实例。
  • 视图类型错误:项布局中是EditText,但ViewHolder里错误用TextView去绑定,导致无法正确操作输入框。
  • 未同步输入内容:未处理EditText的文本变化,导致列表更新时输入内容丢失。

修正后的代码

MainActivity代码

class AjoutObjectifActivity : AppCompatActivity() {

    private var etapes: ArrayList<String> = ArrayList()
    private lateinit var binding: ActivityAjoutObjectifBinding
    private lateinit var adapterEtapes: EtapesAdapter // 全局保存适配器实例

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityAjoutObjectifBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 初始化RecyclerView布局管理器
        binding.recyclerViewObjectifsEtapes.layoutManager = LinearLayoutManager(this)
        // 初始化适配器并绑定数据回调
        adapterEtapes = EtapesAdapter(etapes) { position, text ->
            etapes[position] = text
        }
        binding.recyclerViewObjectifsEtapes.adapter = adapterEtapes

        setupButtons()
    }

    private fun setupButtons() {
        binding.buttonAddEtape.setOnClickListener{
            addEtape()
        }
    }

    private fun addEtape() {
        val newIndex = etapes.size
        etapes.add("")
        // 局部通知适配器插入新项,避免全量刷新
        adapterEtapes.notifyItemInserted(newIndex)
        // 自动滚动到新添加的输入框
        binding.recyclerViewObjectifsEtapes.scrollToPosition(newIndex)
    }
}

EtapesAdapter代码

class EtapesAdapter(
    private val etapes: ArrayList<String>,
    private val onTextChanged: (Int, String) -> Unit // 回调同步输入内容
) : RecyclerView.Adapter<EtapesAdapter.EtapeViewHolder>() {

    override fun getItemCount(): Int = etapes.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EtapeViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_etapes_input, parent, false)
        return EtapeViewHolder(view, onTextChanged)
    }

    override fun onBindViewHolder(holder: EtapeViewHolder, position: Int) {
        holder.bind(etapes[position], position)
    }

    class EtapeViewHolder(
        itemView: View,
        private val onTextChanged: (Int, String) -> Unit
    ) : RecyclerView.ViewHolder(itemView) {

        // 正确绑定EditText类型
        private val etapeEt: EditText = itemView.findViewById(R.id.edit_text_etapes_objectif)
        private var currentPosition: Int = -1

        init {
            // 添加文本变化监听,实时同步到数据源
            etapeEt.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) {
                    if (currentPosition != -1) {
                        onTextChanged.invoke(currentPosition, s.toString())
                    }
                }

                override fun afterTextChanged(s: Editable?) {}
            })
        }

        fun bind(text: String, position: Int) {
            currentPosition = position
            // 避免光标跳动,仅在内容不同时更新文本
            if (etapeEt.text.toString() != text) {
                etapeEt.setText(text)
            }
        }
    }
}

主布局优化(移除不必要的ScrollView)

<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view_objectifs_etapes"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"/>

内容的提问来源于stack exchange,提问作者Compteur_Linky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:20:26