【问题标题】:Implementing click listener for RecyclerView adapter correctly正确实现 RecyclerView 适配器的点击监听器
【发布时间】:2019-02-28 22:12:40
【问题描述】:

RecyclerView 适配器中的项目创建点击侦听器的正确方法是什么? This tutorial 说应该在 onBindViewHolder 中完成,但其他人在 onCreateViewHolder 中说,我没有看到后者的任何教程,因此我很困惑。

class MyRVAdapter(private val myList: ArrayList<Item>) : RecyclerView.Adapter<MyRVAdapter.ViewHolder>() {
    override fun getItemCount(): Int {
        return myList.size
    }

    class ViewHolder (itemView : View):RecyclerView.ViewHolder(itemView) {
        // val myButton = itemView.findViewById<Button>(R.id.btn_A)!!
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.myButton.text = (myList[position].btnTitle)
     }

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

        val myButton = v.findViewById<Button>(R.id.btn_A)!!

        myButton.setOnClickListener {
            customView = View.inflate(holder.itemView.context, R.layout.fragment_dialog, null)

                val builder = AlertDialog.Builder(holder.itemView.context)
                builder.setIconAttribute(R.attr.imgInfo)
                builder.setTitle(R.string.dialog_title)
                builder.setView(customView)
                builder.setPositiveButton(android.R.string.ok){ dialog, _ -> dialog.dismiss() }
                builder.show()
        }
    }
}

【问题讨论】:

  • 又是你),我以为你明白我的建议。只需剪切 onBindViewHolder() 中的代码 holder.myButton.setOnClickListener {//所有代码} 并粘贴到class ViewHolder 并删除所有holder.
  • @underoid 我可以把holder: ViewHolder移到onCreateViewHolder吗?
  • 您无需执行任何其他操作。你还有问题吗?
  • @underoid 是的。我也收到此错误:'onCreateViewHolder' overrides nothing.
  • @MacaronLover 在 onBindViewHolder 内部使用点击监听器。在 Java 中使用了 onClickListener 的用法。在创建视图之前使用新的单击侦听器。它可能会抛出错误或异常。所以在 onBindViewHolder 中使用 onClickListener 很好

标签: android kotlin android-recyclerview onitemclicklistener


【解决方案1】:

在 Kotlin 中

在 Kotlin 中,您不能直接在 ViewHolderClass 中实现 onClickListener。 在Kotlin中要实现同样的,你必须在onBindViewHolder里面做onClickListener

holder.myButton.setOnClickListener {
            //do your stuff here
}

或者使用初始化函数

// I'm not sure this is a correct method or not

class MyRVAdapter : RecyclerView.Adapter<MyRVAdapter.ViewHolder>() {


    override fun getItemCount(): Int {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }


    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyRVAdapter.ViewHolder {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
        var myButton = itemView.findViewById(R.id.button) as Button

         // use any of the following declaratons
         // val myButton = itemView.findViewById(R.id.button) as Button
         // val myButton = itemView.findViewById<Button>(R.id.button)
         // var myButton = itemView.findViewById<Button>(R.id.button)
         // var myButton:Button = itemView.findViewById(R.id.button)
         // val myButton:Button = itemView.findViewById(R.id.button)


        // to avoid Expecting Member Declaration is showing in kotlin  use constructor
       // Expecting Member Declaration is showing because kotlin allows null declaration so a constructor or init is required to avoid this
        init {
            myButton.setOnClickListener{
                //do your stuff here
            }
        }

    }
}

在 Java 中

onBindViewHolder 将在数据发生变化时执行。所以最好把onClickListener写在ViewHolderClass中。

myButton.setOnClickListener {
            //do your stuff here
}

【讨论】:

  • 是的。对困惑感到抱歉。我现在用 kotlin 试过了。 kotlin 不允许与 java 相同
  • @MacaronLover 我已经用解释更新了我的答案。试着读一下。我想它会对你有所帮助。并通过这个stackoverflow.com/questions/44368741/…
  • 除了我已经回答的问题之外,您唯一回答的是:在 Kotlin 中,您无法在 ViewHolderClass 中实现 onClickListener。 这是不对的。
  • 哪个更好用?:val myButton = itemView.findViewById&lt;Button&gt;(R.id.button)!! or var myButton = itemView.findViewById(R.id.button) as Button?
  • @MacaronLover as Button 没用看我的回答
【解决方案2】:

onBindViewHolder() 将在您的视图出现在屏幕上时一直被调用,因此它被调用的次数超过您的项目数。滚动时,您将创建许多重复的侦听器。在 ViewHolder 中设置监听器将为每个持有者创建一个监听器。代码如下:

class MyRVAdapter() : RecyclerView.Adapter<MyRVAdapter.ViewHolder>() {

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.myButton.text = "set here all except listener"
    }

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

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

    class ViewHolder (itemView: View) : RecyclerView.ViewHolder(itemView) {

        var myButton: Button = itemView.findViewById(R.id.btn_A)

        init {
            myButton.setOnClickListener {
                val customView = View.inflate(itemView.context, R.layout.fragment_dialog, null)

                val builder = AlertDialog.Builder(itemView.context)
                builder.setIconAttribute(R.attr.imgNight)
                builder.setTitle(R.string.dialog_title)
                builder.setView(customView)
                builder.setPositiveButton(android.R.string.ok){ dialog, _ -> dialog.dismiss() }
                builder.show()

                val tabLayout = customView.findViewById(R.id.mTabLayout)
                val viewPager = customView.findViewById(R.id.mViewPager)

                val adapter = TabbedDialogAdapter(childFragmentManager)//i dont understand how you get this but it is another question
                adapter.addFragment("Tab A", TabbedDialogFragment.createInstance("Description A"))
                adapter.addFragment("Tab B", TabbedDialogFragment.createInstance("Description B"))
                adapter.addFragment("Tab C", TabbedDialogFragment.createInstance("Description C"))

                viewPager.adapter = adapter
                tabLayout.setupWithViewPager(viewPager)
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多