Closed. This question is opinion-based。它当前不接受答案。












想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。

去年关闭。



Improve this question




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

我已经尝试过特质(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

有什么建议?

最终得到了认可答案的变体

在 Activity 中定义了功能:
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)
    }
}

通过循环在以下批准的答案中扩展功能。
fun <T : RecyclerView.ViewHolder> T.onClick(event: (view: View, position: Int, type: Int) -> Unit): T {
    itemView.setOnClickListener {
        event.invoke(it, getAdapterPosition(), getItemViewType())
    }
    return this
}

最佳答案

我有一些不同的方法。您可以为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) {

    }
}

我正在与library的同事一起提供此类扩展名。

08-18 17:16
查看更多