【问题标题】:How to create instance of generic class passing a method reference in constructor with kotlin如何使用kotlin在构造函数中创建传递方法引用的泛型类实例
【发布时间】:2017-09-21 14:09:43
【问题描述】:

现在我使用 kotlin 作为我的主要编程语言,我正在尝试简化 Android 的 Recyclerview 实现逻辑,但我被困在以下几点:

假设我定义了以下 ViewHolder 类,其中点击位置事件通过构造函数中的方法引用传播。

class CustomViewHolder(itemView: View, val onClick: (Int) -> Unit)) : RecyclerView.ViewHolder(itemView){
    itemView.setOnClickListener {
        onClick.invoke(adapterPosition)
    } 
}

如何构建在构造函数中具有方法引用的泛型类的实例?

我的 recyclerview 实现在构造函数中有一个通用类,还有一个实体引用,可以通过 onCreateViewHolder 的反射创建我的 CustomViewHolder 类的实例:

class CustomAdapter<HolderClassGeneric>(val entityClass: Class<HolderClassGeneric>) : RecyclerView.Adapter<HolderClassGeneric>() {

    /*
    Usual recyclerview stuff
    */ 

    //Method that I want to be called when a list item is clicked
    fun onListItemClicked(position: Int) {
       //do stuff
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HolderClassGeneric {
        val view = LayoutInflater.from(parent.context).inflate(listItemLayoutResourceId, parent, false)

        val constructor: Constructor<HolderClassGeneric>
        val instance: HolderClassGeneric
                                                            //I'M STUCK HERE
        constructor = entityClass.getConstructor(View::class.java, ?¿?¿?¿?¿)
        instance = constructor.newInstance(view, this::onListItemClicked)

        return instance

}

如果我想实现的目标是不可能的,是否可以通过反射使用setter传递方法引用?

【问题讨论】:

    标签: android generics reflection kotlin


    【解决方案1】:

    Kotlin lambda 通常被翻译为 FunctionX 对象,它的参数数量是 X,所以如果您正在寻找像 (Int) -&gt; Unit 这样的 lambda 函数的表示形式,它会是 Function1&lt;Int, Unit&gt;,所以您可以简单地做:

    entityClass.getConstructor(View::class.java, Function1::class.java)
    

    【讨论】:

      【解决方案2】:

      你可以使用像工厂这样的参数函数。

      class CustomAdapter<HolderClassGeneric>(val entityFactory: (View,  (Int) -> Unit) -> HolderClassGeneric) : RecyclerView.Adapter<HolderClassGeneric>() {
      
          /*
          Usual recyclerview stuff
          */ 
      
          //Method that I want to be called when a list item is clicked
          fun onListItemClicked(position: Int) {
             //do stuff
          }
      
          override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HolderClassGeneric {
              val view = LayoutInflater.from(parent.context).inflate(listItemLayoutResourceId, parent, false)
      
              val instance = entityFactory(view, this::onListItemClicked)
      
              return instance
      
      }
      

      【讨论】:

      • 对不起,这不是我要找的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-27
      • 2023-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多