为什么我的 RecyclerView 可以正常滚动,但不能执行 onItemClick 方法?

Why does my RecyclerView scroll properly but NOT perform onItemClick method?

提问人:Kera Linn 提问时间:11/10/2023 更新时间:11/16/2023 访问量:37

问:

我正在 Android Studio 中处理一个 Kotlin 项目。我已经定义了自己的适配器,并在我的活动中实现了RecyclerView。RecyclerView 正确填充数据并允许我滚动,但它似乎没有注册 onItemClick(position: Int) 方法的点击次数。

目前,onItemClick 方法在 Adapter 中声明为接口 RecyclerViewEvent。这允许我在声明和附加适配器时在我的 Activity 中实现侦听器。然后,我在 Activity 中实现了 onItemClick 方法。

当我在模拟器中运行项目时,它会创建 RecyclerView 并使用正确的数据填充它。我可以沿着它滚动(上下),但是当我单击行时没有任何反应。我能听到它在“咔哒”一声,所以我知道它正在接收触摸。我尝试只做一个简单的 toast 消息并为 onItemClick 方法启动一个新的意图(无论如何我都需要它这样做)。

没有抛出任何错误,也不会破坏程序。不知道还有什么可以尝试的。

这是我的适配器:

class GuidedMeditationAdapter(
    private val data: List<GuidedMeditationData>,
    private val listener: RecyclerViewEvent,
) : RecyclerView.Adapter<GuidedMeditationAdapter.ViewHolder>(){

    inner class ViewHolder(view: View): RecyclerView.ViewHolder(view), View.OnClickListener{
        val textView: TextView = view.findViewById(R.id.gmrowtextview)
        init {
            view.setOnClickListener(this)
        }
        override fun onClick(v: View?) {
            val position = bindingAdapterPosition
            if (position != RecyclerView.NO_POSITION){
                listener.onItemClick(position)
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflatedView: View = LayoutInflater.from(parent.context)
            .inflate(R.layout.fragment_meditation_recyclerview_row,parent,false)
        return ViewHolder(inflatedView)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val selection: GuidedMeditationData = data[position]
        holder.textView.text = selection.trackName
        holder.textView.setBackgroundResource(selection.gmImages)
        holder.textView.setOnClickListener{listener}
    }

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

    interface RecyclerViewEvent {
        fun onItemClick(position: Int)
    }

}

然后像这样实现到我的活动中:

class GuidedMeditationActivity : AppCompatActivity(),
    GuidedMeditationAdapter.RecyclerViewEvent {

    private val data = createData()
    private lateinit var listener: OnClickListener
   
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.layout_guided_meditation) 

        val recyclerView: RecyclerView = findViewById(R.id.gm_recyclerview)
        recyclerView.adapter = GuidedMeditationAdapter(data,this)
        recyclerView.layoutManager = LinearLayoutManager(this)
    }

    override fun onItemClick(position: Int) {
        val userPick = data[position]
        val intent = Intent(this,GuidedMeditationExoPlayer::class.java)
        startActivity(intent)
        Toast.makeText(this, userPick.trackName,Toast.LENGTH_SHORT).show()
    }

  private fun createData(): List<GuidedMeditationData> {
      val title = GuidedMeditationDataRepo.gmNames
      val trackId = GuidedMeditationDataRepo.soundcloudTrackID
      val img = GuidedMeditationDataRepo.gmImgs
      val audIds = GuidedMeditationDataRepo.gmGoogleAudIds
      val vidIds = GuidedMeditationDataRepo.gmGoogleVidIds

      val gmData = ArrayList<GuidedMeditationData>()
      for (i in 0..5) {
          gmData.add(
              GuidedMeditationData(
                  title[i],
                  trackId[i],
                  img[i],
                  audIds[i],
                  vidIds[i]
              )
          )
      }
      return gmData
  }
}

提前感谢您的阅读和帮助!

Kotlin 方法 android-recycler查看 onclick android-adapter

评论


答:

0赞 Cavala 11/10/2023 #1

如果我理解您的问题,您希望在单击回收器视图中的项目时添加操作,具体取决于位置。 我不是专家,我最近开始使用 Kotlin 编码。

关于你的适配器,它似乎没问题,但是在你的活动中,如果你想要一个取决于位置的动作,你必须声明所有。

例如,对于位置 0(第一个位置)=>您需要“操作 1”。对于位置 1 =>,您需要“操作 2”。

因此,我建议你对 recyclerView 中的每个位置使用“when”条件

像这样,在您的活动中:

override fun onItemClick(position: Int) {
    when (position) {
    0 -> startActivity(Intent(this,GuidedMeditationExoPlayer::class.java))
    1 -> Toast.makeText(this, userPick.trackName,Toast.LENGTH_SHORT).show()
}

希望这会有所帮助

编辑: 那么,让我们看看你的适配器。

您可以从适配器中删除 onClick 函数,因为 Activity 中的 onItemClick 函数就足够了。

如果这样做,则也不需要接口 RecyclerViewEvent,因此可以将其删除。

在 init 中,将 init 替换为: val position = adapterPosition listener.onClick(位置)

在 onBindViewHolder 中,无需输入 setOnClickListener。Activity 中的 init 和 onClick 就足够了。

在 Activity 中,使用 when 方法添加 onItemClick 函数。

希望这次会有所帮助! (我的箭不好......

评论

0赞 Kera Linn 11/10/2023
嗨,卡瓦拉!感谢您的回复!我改变了我的方法,之后我不得不删除箭头,但没有运气!我仍然能听到它的咔嗒声,但它什么也没做。它没有中断或给我一个错误,但它既没有执行 Toast 消息也没有执行新意图。when (position)
0赞 Kera Linn 11/29/2023
嗨,卡瓦拉!感谢您再次回复!实际上,我被迫将我的工作迁移到使用 Jetpack Compose,因此我最终重新编写了整个 RecyclerView 代码并以这种方式解决了我的问题。但是当我回到旧活动时,您的答案奏效了!谢谢!!
0赞 Sai Dilip 11/16/2023 #2

尝试将侦听器传递给 Viewholder

inner class ViewHolder(view: View , listner : RecyclerViewEvent): RecyclerView.ViewHolder(view), View.OnClickListener{
    val textView: TextView = view.findViewById(R.id.gmrowtextview)
    init {
        view.setOnClickListener(this)
    }
    override fun onClick(v: View?) {
        val position = bindingAdapterPosition
        if (position != RecyclerView.NO_POSITION){
            listener.onItemClick(position)
        }
    }
}

它对我有用.. 希望它有效

评论

0赞 Kera Linn 11/29/2023
嗨,赛!感谢您的回复!实际上,我被迫将我的工作迁移到使用 Jetpack Compose,因此我最终重新编写了整个 RecyclerView 代码并以这种方式解决了我的问题。