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

Dan*_*ele 6 android kotlin android-recyclerview

我为我的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()
                            }
                        }
                    }
            )
Run Code Online (Sandbox Code Playgroud)

使用我翻译成Kotlin的ItemClickSupport库.

我在object(第2行)上收到错误消息:

object必须声明为abstract或实现抽象成员.

我是Kotlin的新手,我也找不到任何解决方案.

任何帮助是极大的赞赏.

编辑:

这是我的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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个包含整个错误的屏幕截图及其发生的位置:

截图

Jay*_*ard 7

您的界面和方法签名不匹配.您的界面将一个函数声明为:

fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View)
Run Code Online (Sandbox Code Playgroud)

并将其覆盖为:

fun onItemClicked(recyclerView: RecyclerView?, position: Int, v: View?)
Run Code Online (Sandbox Code Playgroud)

那些方法签名不一样.

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

override fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View)
Run Code Online (Sandbox Code Playgroud)

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

如果你想让这个代码更加惯用Kotlin你需要函数引用或lambdas而不是接口,你应该这样做而不是依赖于SAM转换.您可以在高阶函数和Lambdas中阅读更多相关信息.更详细地说,这超出了您的问题的范围.