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

Fragment中RecyclerView的onItemClick事件未触发问题排查

问题原因分析

你的RecyclerView点击事件未触发,核心问题在于重复设置Adapter且新Adapter未绑定点击监听:

  1. 你先初始化了基于空列表的TaskAdapter(list),并给这个adapter绑定了点击监听,随后将它设置给RecyclerView。
  2. 但API请求成功后,你又创建了一个全新的TaskAdapter(response.body()!!),直接替换了RecyclerView的adapter。这个新adapter没有调用setOnItemClickListener,所以实际显示的列表根本没有绑定点击事件。

另外还有一个潜在问题:点击监听里使用的是初始空列表list,但实际显示的是API返回的数据源,就算点击能触发,也会因为数组越界崩溃。


修复方案

推荐采用复用Adapter+更新数据的方式,避免重复创建Adapter,同时保证点击监听始终有效:

第一步:修改TaskAdapter,添加数据更新方法

class TaskAdapter(var list: List<TasksItem>) : RecyclerView.Adapter<TaskAdapter.MyViewHolder>() {

    private var listener2: OnItemClickListener? = null

    interface OnItemClickListener {
        fun onItemClick(position: Int)
    }

    fun setOnItemClickListener(listener: OnItemClickListener){
        listener2 = listener
    }

    // 添加数据更新方法
    fun updateData(newList: List<TasksItem>) {
        this.list = newList
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item, parent,false)
        return MyViewHolder(itemView,listener2)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val currentitem = list[position]
        holder.TaskName.text = currentitem.taskName
        holder.Date.text = currentitem.dueDate
        holder.Assignee.text = currentitem.assignee
        holder.Status.text = currentitem.taskStatus
    }

    override fun getItemCount(): Int {
        return list.size
    }

    class MyViewHolder(itemView : View, listener: OnItemClickListener?) : RecyclerView.ViewHolder(itemView){
        val TaskName : TextView = itemView.findViewById(R.id.tvTaskname)
        val Assignee : TextView = itemView.findViewById(R.id.tvAssignee)
        val Date : TextView = itemView.findViewById(R.id.tvDate)
        val Status : TextView = itemView.findViewById(R.id.tvStatus)

        init {
            itemView.setOnClickListener{
                listener?.onItemClick(adapterPosition)
            }
        }
    }
}

第二步:修改Fragment1的onViewCreated逻辑

class Fragment1 : Fragment() {
    private lateinit var binding: Fragment1Binding
    private lateinit var list : ArrayList<TasksItem>
    private lateinit var recyclerView: RecyclerView
    private lateinit var manager: RecyclerView.LayoutManager
    private lateinit var myAdapter: TaskAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_1, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        recyclerView = view.findViewById(R.id.app_list)
        recyclerView.setHasFixedSize(true)

        list = arrayListOf()
        manager = LinearLayoutManager(this.requireContext())

        // 初始化Adapter并绑定点击监听
        myAdapter = TaskAdapter(list)
        recyclerView.layoutManager = manager
        recyclerView.adapter = myAdapter

        myAdapter.setOnItemClickListener(object : TaskAdapter.OnItemClickListener {
            override fun onItemClick(position: Int) {
                // 直接使用Adapter内的数据源,避免不一致
                val currentTask = myAdapter.list[position]
                val intent = Intent(activity, ViewTaskActivity::class.java).apply{
                    putExtra("taskname", currentTask.taskName)
                    putExtra("desc", currentTask.taskDesc)
                    putExtra("category", currentTask.category)
                    putExtra("duedate", currentTask.dueDate)
                    putExtra("assignee", currentTask.assignee)
                    putExtra("point", currentTask.pointEarned)
                    Log.d("Fragment1", "onItemClick executed, position: $position")
                }
                startActivity(intent)
            }
        })

        // API请求:更新Adapter数据而非重新创建
        GroomedKidzApi.retrofitService.getTasksProgress().enqueue(object :
            Callback<List<TasksItem>?> {
            override fun onResponse(
                call: Call<List<TasksItem>?>,
                response: Response<List<TasksItem>?>
            ) {
                val responseBody = response.body()
                if (responseBody != null) {
                    myAdapter.updateData(responseBody)
                    Log.e("TAG", "response 33: "+ responseBody)
                }
            }

            override fun onFailure(call: Call<List<TasksItem>?>, t: Throwable) {
                Log.e("TAG", "API请求失败", t)
            }
        })
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:05:41