如何用Kotlin实现RecyclerView项分数计数器?问题排查及代码修正
问题排查与解决方案
错误原因总结
- 无持久化数据集合:适配器仅用字符串数组存储名称,每次绑定
ViewHolder时都创建新的Surveys临时实例,导致修改的计数无法保存,刷新后直接重置为0。 - 未绑定计数显示:
ViewHolder的绑定方法中没有将countNumber赋值给surveyNumber文本控件,即使计数变化也不会在界面上显示。 - 回调修改临时对象:Activity中修改的是每次绑定生成的临时
Surveys对象,而非适配器中持久存储的真实数据对象。
修正后的代码
数据类(保持不变)
data class Surveys( val surveyName: String, var countNumber: Int, )
RecyclerView适配器
class SurveyAdapter(val changeNumberCallBack: ChangeNumberCallBack) : RecyclerView.Adapter<SurveyAdapter.SurveyViewHolder>() { // 用MutableList存储持久化的Survey数据,初始化每个项计数为0 private val surveyList = mutableListOf( Surveys("A", 0), Surveys("B", 0), Surveys("C", 0), Surveys("D", 0) ) inner class SurveyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { private val surveyName: TextView = itemView.findViewById(R.id.itemName) private val mediaBtn: ImageView = itemView.findViewById(R.id.mediaBtn) private val decreaseBtn: ImageView = itemView.findViewById(R.id.decreaseNumber) private val increaseBtn: ImageView = itemView.findViewById(R.id.increaseNumber) private val surveyNumber: TextView = itemView.findViewById(R.id.countNumber) fun bind(survey: Surveys, position: Int) { // 绑定名称和当前计数到控件 surveyName.text = survey.surveyName surveyNumber.text = survey.countNumber.toString() decreaseBtn.setOnClickListener { changeNumberCallBack.onDecreaseNumber(position) } increaseBtn.setOnClickListener { changeNumberCallBack.onIncreaseNumber(position) } mediaBtn.setOnClickListener { changeNumberCallBack.onMediaClick() } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyViewHolder { return SurveyViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.survey_item, parent, false) ) } override fun getItemCount(): Int = surveyList.size override fun onBindViewHolder(holder: SurveyViewHolder, position: Int) { // 绑定集合中持久化的对应项 holder.bind(surveyList[position], position) } // 供外部调用,修改对应位置计数并刷新UI fun increaseCount(position: Int) { surveyList[position].countNumber++ notifyItemChanged(position) } fun decreaseCount(position: Int) { // 可选:防止计数变为负数 if (surveyList[position].countNumber > 0) { surveyList[position].countNumber-- notifyItemChanged(position) } } interface ChangeNumberCallBack { fun onIncreaseNumber(position: Int) fun onDecreaseNumber(position: Int) fun onMediaClick() } }
Activity类
class SurveyActivity : AppCompatActivity(), SurveyAdapter.ChangeNumberCallBack { private lateinit var surveyAdapter: SurveyAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_survey) val surveyRv: RecyclerView = findViewById(R.id.main_rv) surveyRv.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false) surveyAdapter = SurveyAdapter(this) surveyRv.adapter = surveyAdapter } override fun onIncreaseNumber(position: Int) { surveyAdapter.increaseCount(position) } override fun onDecreaseNumber(position: Int) { surveyAdapter.decreaseCount(position) } override fun onMediaClick() { startActivity(Intent(this, MediaSurveyActivity::class.java)) } }
关键修改说明
- 新增持久化数据集合:用
MutableList<Surveys>存储每个项的名称和计数,确保修改后的状态能被保存。 - 调整回调参数:将回调中的
Surveys对象改为position,让Activity通知适配器修改对应位置的真实数据,避免临时对象问题。 - 完善ViewHolder绑定逻辑:在
bind方法中为surveyNumber设置文本,让计数能显示在界面上。 - 适配器内部处理数据更新:在适配器中实现计数增减逻辑并调用
notifyItemChanged刷新单个项,性能优于全局刷新的notifyDataSetChanged。 - 添加负数防护:可选限制计数不能小于0,提升用户体验。
内容的提问来源于stack exchange,提问作者KMD
相关产品推荐
相关产品推荐

