Реализация прослушивателя щелчков для адаптера RecyclerView правильно - PullRequest
0 голосов
/ 01 марта 2019

Как правильно создать прослушиватель кликов для элемента в адаптере RecyclerView? В этом уроке сказано, что это должно быть сделано в 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()
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 01 марта 2019

В Kotlin

В Kotlin вы не можете напрямую реализовать onClickListener в ViewHolderClass.В Kotlin, чтобы добиться того же, вы должны сделать onClickListener внутри onBindViewHolder

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
}
0 голосов
/ 01 марта 2019

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)
            }
        }
    }
}
0 голосов
/ 01 марта 2019

Правильный способ - заставить его работать в самом простом виде.
Можете ли вы назначить слушателя "впереди" с onCreateViewHolder, и если да, то почему бы вам этого не сделать?
Примите во внимание тот факт, что onBindViewHolder будет выполняться неоднократно.
Если вы не получите новые данные, влияющие на ваше представление после создания видоискателя, не должно быть никаких причин менять слушателя «во время выполнения» из повторяющихся onBindViewHolder вызовов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...