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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:57:50