Android - Kotlin - object must be declared abstract or implement abstract member

匿名 (未验证) 提交于 2019-12-03 02:29:01

问题:

I have set an ItemClickLister for my RecyclerView like this:

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

using the ItemClickSupport library which I translated into Kotlin.

I get an error on object (line 2) that says:

object must be declared abstract or implement abstract member.

I'm really new to Kotlin and I couldn't find any solution here on SO either.

Any help is greatly appreciated.

Edit:

Here is my 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         }     } } 

This is a screenshot with the whole error and where it happens:

回答1:

Your interface and method signatures do not match. Your interface is declaring one function as:

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

And you override it as:

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

Those are not the same method signatures.

If this was a Java interface, you can override while changing nullability because it isn't clear what the nullability is (given no annotations in the Java code). But since you ported it to a Kotlin interface you must override using the same exact signature. You instead made both RecyclerView? and View? nullable which results in a mismatch to the original signature. Change your overridden function to be:

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

Since this is a Kotin interface, you cannot use the SAM conversion to a Lambda so that is why the other answer previously provided does not work. If this was a Java interface, you could do that. You can track SAM conversions for Kotlin interfaces in KT-7770.

If you wanted this code to be more idiomatic Kotlin you would want function references or lambdas instead of interfaces, and you should just do that instead of relying on SAM conversion. You can read more about that in Higher-Order Functions and Lambdas. This is outside the scope of your question to go into more detail.



回答2:

Try with it:

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


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!