Android – Kotlin – 对象必须声明为抽象或实现抽象成员

我为我的RecyclerView设置了一个ItemClickLister,像这样:

ItemClickSupport.addTo(recyclerView!!).setOnItemClickListener( object : ItemClickSupport.OnItemClickListener { override fun onItemClicked(recyclerView: RecyclerView?, position: Int, v: View?) { val row = recyclerView!!.getChildAt(position) val el = row.findViewById(R.id.active_expandablelayout) as ExpandableLayout if (el.isExpanded) { el.collapse() } else { el.expand() } } } ) 

使用我翻译成Kotlin的ItemClickSupport库。

我得到一个object (第2行)的错误,说:

对象必须声明为抽象或实现抽象成员。

我对Kotlin来说真的很陌生,在SO上我也找不到任何解决方案。

任何帮助是极大的赞赏。

编辑:

这是我的ItemClickSupport.kt

 class ItemClickSupport private constructor(private val mRecyclerView: RecyclerView) { private var mOnItemClickListener: OnItemClickListener? = null private var mOnItemLongClickListener: OnItemLongClickListener? = null private val mOnClickListener = View.OnClickListener { v -> if (mOnItemClickListener != null) { val holder = mRecyclerView.getChildViewHolder(v) mOnItemClickListener!!.onItemClicked(mRecyclerView, holder.adapterPosition, v) } } private val mOnLongClickListener = View.OnLongClickListener { v -> if (mOnItemLongClickListener != null) { val holder = mRecyclerView.getChildViewHolder(v) return@OnLongClickListener mOnItemLongClickListener!!.onItemLongClicked(mRecyclerView, holder.adapterPosition, v) } false } private val mAttachListener = object : RecyclerView.OnChildAttachStateChangeListener { override fun onChildViewAttachedToWindow(view: View) { if (mOnItemClickListener != null) { view.setOnClickListener(mOnClickListener) } if (mOnItemLongClickListener != null) { view.setOnLongClickListener(mOnLongClickListener) } } override fun onChildViewDetachedFromWindow(view: View) { } } init { mRecyclerView.setTag(R.id.item_click_support, this) mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener) } fun setOnItemClickListener(listener: OnItemClickListener): ItemClickSupport { mOnItemClickListener = listener return this } fun setOnItemLongClickListener(listener: OnItemLongClickListener): ItemClickSupport { mOnItemLongClickListener = listener return this } private fun detach(view: RecyclerView) { view.removeOnChildAttachStateChangeListener(mAttachListener) view.setTag(R.id.item_click_support, null) } interface OnItemClickListener { fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View) } interface OnItemLongClickListener { fun onItemLongClicked(recyclerView: RecyclerView, position: Int, v: View): Boolean } companion object { fun addTo(view: RecyclerView): ItemClickSupport { var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as ItemClickSupport if (support == null) { support = ItemClickSupport(view) } return support } fun removeFrom(view: RecyclerView): ItemClickSupport { val support = view.getTag(R.id.item_click_support) as ItemClickSupport support?.detach(view) return support } } } 

这是整个错误的截图,它发生在哪里:

截图

您的界面和方法签名不匹配。 你的接口声明了一个函数:

 fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View) 

你重写它为:

 fun onItemClicked(recyclerView: RecyclerView?, position: Int, v: View?) 

那些方法签名不一样。

如果这是一个Java接口,则可以在改变可空性时重写,因为不清楚可空性是什么(Java代码中没有注释)。 但是,由于您将其移植到Kotlin界面,您必须使用相同的确切签名进行覆盖。 你反而做了两个RecyclerView?View? 可空,导致与原始签名不匹配。 改变你的覆盖函数是:

 override fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View) 

由于这是一个Kotin接口,因此您不能使用SAM转换为Lambda,因此之前提供的其他答案不起作用。 如果这是一个Java界面,你可以做到这一点。 您可以在KT-7770中跟踪Kotlin接口的SAM转换。

如果你想让这个代码更加地道的Kotlin,你会想要函数引用或lambdas而不是接口,你应该这样做,而不是依靠SAM转换。 你可以在高阶函数和Lambdas中阅读更多。 这是超出你的问题的范围进入更多的细节。

尝试一下:

 ItemClickSupport.addTo(listView).setOnItemClickListener(object : ItemClickSupport.OnItemClickListener{ override fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View) { val row = recyclerView!!.getChildAt(position) val el = row.findViewById(R.id.active_expandablelayout) as ExpandableLayout if (el.isExpanded) { el.collapse() } else { el.expand() } } })