Kotlin 中的 RecyclerView itemClickListener

新手上路,请多包涵

经过 3 年的 Android 经验后,我正在用 Kotlin 编写我的第一个应用程序。只是对如何在 Kotlin 中使用带有 RecyclerView 的 itemClickListener 感到困惑。

我已经尝试过 trait (edit: now interface) 方法,非常类似于 Java

 public class MainActivity : ActionBarActivity() {

  protected override fun onCreate(savedInstanceState: Bundle?) {

    // set content view etc go above this line

    class itemClickListener : ItemClickListener {
      override fun onItemClick(view: View, position: Int) {
        Toast.makeText(this@MainActivity, "TEST: " + position, Toast.LENGTH_SHORT).show()
      }
    }

    val adapter = DrawerAdapter(itemClickListener())
    mRecyclerView.setAdapter(adapter)
 }

  trait ItemClickListener {
    fun onItemClick(view: View, position: Int)
  }
}

这似乎非常多余,所以我尝试了内部类方法:

 inner class ItemClickListener {
    fun onItemClick(view: View, position: Int) {
        startActivityFromFragmentForResult<SelectExerciseActivity>(SELECT_EXERCISES)
    }
}

然后像这样设置适配器的点击监听器:

 val adapter = WorkoutsAdapter(ItemClickListener())

但我仍然对此不满意,因为我认为可能有更好、更清洁的方法。我试图从本质上实现这样的目标: RecyclerView onClick

有什么建议么?

最终得到了批准答案的变体

在活动中定义函数:

 val itemOnClick: (View, Int, Int) -> Unit = { view, position, type ->
    Log.d(TAG, "test")
}

像这样将函数本身传递给适配器:

 class ExercisesAdapter(val itemClickListener: (View, Int, Int) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
      // other stuff up here
      val vhExercise = ExerciseVH(view) // view holder
      // on to the view holder through the extension function
      vhExercise.onClick(itemClickListener)
    }
}

Loop 在下面批准的答案中的扩展功能。

 fun <T : RecyclerView.ViewHolder> T.onClick(event: (view: View, position: Int, type: Int) -> Unit): T {
    itemView.setOnClickListener {
        event.invoke(it, getAdapterPosition(), getItemViewType())
    }
    return this
}

原文由 Afzal N 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 809
2 个回答

我有一点不同的方法。您可以为您的 ViewHolder 创建一个扩展

fun <T : RecyclerView.ViewHolder> T.listen(event: (position: Int, type: Int) -> Unit): T {
    itemView.setOnClickListener {
        event.invoke(getAdapterPosition(), getItemViewType())
    }
    return this
}

然后像这样在适配器中使用它

class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    val items: MutableList<String> = arrayListOf()

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyViewHolder? {
        val inflater = LayoutInflater.from(parent!!.getContext())
        val view = inflater.inflate(R.layout.item_view, parent, false)
        return MyViewHolder(view).listen { pos, type ->
            val item = items.get(pos)
            //TODO do other stuff here
        }
    }

    override fun onBindViewHolder(holder: MyViewHolder?, position: Int) {

    }

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

    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    }
}

我正在与我的同事一起开发提供此类扩展的

原文由 Damian Petla 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是一种不使用接口的简单方法,只需在您的适配器中在 viewholder 类中创建一个 init 块。像下面

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    init {
        itemView.setOnClickListener{
            //your code here---
        }
    }
}

原文由 Siele Kim 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏