在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()
}
}
}
答案 0 :(得分:0)
正确的方法是使其以最简单的形式工作。
您可以从onCreateViewHolder
分配侦听器“提前”吗?如果可以,为什么不呢?
考虑一下onBindViewHolder
将被重复执行的事实。
除非在创建视图持有者之后获得新的数据,否则将没有理由在循环onBindViewHolder
调用中更改“在执行期间”的侦听器。
答案 1 :(得分:0)
在科特林
在Kotlin中,您不能直接在ViewHolderClass中实现onClickListener。
在Kotlin中要实现相同的目的,您必须在onBindViewHolder
holder.myButton.setOnClickListener {
//do your stuff here
}
或使用init函数
// 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
}
答案 2 :(得分:0)
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)
}
}
}
}