Kotlin中RecyclerView动态添加数据失效及点击无响应问题求助
问题描述
通过EditText输入文本,点击按钮向RecyclerView动态添加文本项,点击按钮将文本加入Adapter关联的Array并调用adapter.notifyDataSetChanged()后,RecyclerView既不更新,也无法检测点击事件。但修改Array中已有文本的值(不改变数组长度)时,RecyclerView能正常显示变化。
相关代码
MainActivity.kt
package com.example.recycleviewwork import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View import android.view.View.OnClickListener import android.widget.Button import android.widget.EditText import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView class Travel : AppCompatActivity(), View.OnClickListener { var check_travel_list = arrayOf<String>("cni", "psp", "hhn", "ddp", "ppe", "leh") var state_check_bool = arrayOf<Boolean>(false, false, false, false,false,false) val adapter = travel_list_adapter(check_travel_list,state_check_bool, this) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_travel) var textEditValue = "" // RECYCLEVIEW Travel page val recview_travel = findViewById<RecyclerView>(R.id.travel_recview) recview_travel.layoutManager = LinearLayoutManager(this) recview_travel.adapter = adapter //EDIT text val edit_text_view = findViewById<EditText>(R.id.textedit) // ADD travel button val button_add_travel = findViewById<Button>(R.id.button_travel) button_add_travel.setOnClickListener() { textEditValue = edit_text_view.text.toString() check_travel_list += textEditValue state_check_bool += false adapter.notifyDataSetChanged() println(textEditValue) } } override fun onClick(vue: View) { val index = vue.tag as Int //changement des bool de couleur if(index != null) { state_check_bool[index] = !state_check_bool[index] adapter.notifyDataSetChanged() } } }
Adapter.kt
package com.example.recycleviewwork import android.graphics.Color import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.cardview.widget.CardView import androidx.recyclerview.widget.RecyclerView class travel_list_adapter(val travel_check_list : Array <String>,val travel_state_check : Array<Boolean> , val travel_click : View.OnClickListener) : RecyclerView.Adapter<travel_list_adapter.ViewHolder>() { class ViewHolder (itemview: View ): RecyclerView.ViewHolder(itemview) { val cartview = itemview.findViewById<CardView>(R.id.cartview_travel_list) val text_check = itemview.findViewById<TextView>(R.id.text_travel_list) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): travel_list_adapter.ViewHolder { val inflater = LayoutInflater.from(parent.context) val view_item = inflater.inflate(R.layout.travel_list,parent,false) return ViewHolder(view_item) } override fun getItemCount(): Int { return travel_check_list.size } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val current_check = travel_check_list[position] val state_state_check = travel_state_check[position] holder.cartview.setOnClickListener(travel_click) holder.cartview.tag = position holder.text_check.text = current_check if(state_state_check == true) { holder.text_check.setTextColor(Color.parseColor("#8BC34A")) } else { holder.text_check.setTextColor(Color.parseColor("#000000")) } } }
解决方案
问题核心在于Kotlin Array的不可变性:
- Array是固定长度集合,使用
+=操作符时,并未修改原数组,而是生成了一个新数组对象。但Adapter持有的还是旧数组的引用,调用notifyDataSetChanged()时,读取的依然是旧数组的长度和内容,所以不会更新。 - 修改已有元素时,直接操作的是原数组内的元素,Adapter引用未变,因此能正常刷新。
修复步骤:
- 将Array替换为可变集合
MutableList,支持动态添加元素且不改变引用:// 替换原数组定义 var check_travel_list = mutableListOf<String>("cni", "psp", "hhn", "ddp", "ppe", "leh") var state_check_bool = mutableListOf<Boolean>(false, false, false, false,false,false) - 更新Adapter的参数类型为
MutableList:class travel_list_adapter( val travel_check_list: MutableList<String>, val travel_state_check: MutableList<Boolean>, val travel_click: View.OnClickListener ) : RecyclerView.Adapter<travel_list_adapter.ViewHolder>() { override fun getItemCount(): Int { return travel_check_list.size } // 其他代码保持不变 } - 修改添加元素的逻辑,直接向MutableList中添加:
button_add_travel.setOnClickListener { textEditValue = edit_text_view.text.toString() check_travel_list.add(textEditValue) state_check_bool.add(false) adapter.notifyDataSetChanged() println(textEditValue) }
额外优化建议:
- 用
notifyItemInserted()替代notifyDataSetChanged(),只刷新新增项,提升性能:val newIndex = check_travel_list.size check_travel_list.add(textEditValue) state_check_bool.add(false) adapter.notifyItemInserted(newIndex) - 建议在Adapter内部处理点击事件,避免通过Tag传递索引的潜在问题。
内容的提问来源于stack exchange,提问作者launchcake inc
相关产品推荐
相关产品推荐

