在使用安卓系统3年后,我在Kotlin编写了我的第一个应用程序.

I have tried the trait (edit: now interface) approach, very Java-like

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)
  }
}

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

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

And then just setting the adapter's click listener like this:

val adapter = WorkoutsAdapter(ItemClickListener())

But I'm still not satisfied with this because I think there might be a better, cleaner way. I'm trying to essentially achieve something like this: RecyclerView onClick

Any suggestions?

Ended up going with a variation of the approved answer

在活动中定义了功能:

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

Passed the function itself on to the adapter like this:

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)
    }
}

Extension function by Loop in the approved answer below.

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

推荐答案

I have a little bit different approach. You can create an extension for your ViewHolder

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

Then use it in adapter like 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上提供这样的扩展.

Kotlin相关问答推荐

有什么原因,我得到一个空相关的错误在这个代码

最好的方法来创建一个 map 在kotlin从两个列表

在Kotlin Jetpack中重用下拉菜单

如何将时间值格式化为00:00和00:00:00 Kotlin?""""

Jetpack Compose中的数字 Select 器问题

如何编写带有依赖项的自定义Kotlin串行化程序?

在 detekt 配置文件中找不到某些属性

用于将 0.5 变为 0 的 round() 函数的模拟

区分函数和扩展

高效匹配两个 Flux

Kotlin RxJava 可空的错误

如何在调试中修复 ClassNotFoundException: kotlinx.coroutines.debug.AgentPremain?

无法创建类 ViewModel kotlin 的实例

如何使用 Kotlin Coroutines 使 setOnClickListener debounce 1 秒?

如何处理 Kotlin 中的异常?

防止导航到同一个片段

@uncheckedVariance 在 Kotlin 中?

Android Kotlin .visibility

如何在 Gradle Kotlin DSL 中使用来自 gradle.properties 的插件版本?

Kotlin:测试中的 java.lang.NoSuchMethodError