当前位置: 首页 > 知识库问答 >
问题:

Android-静态编程语言-对象必须声明为抽象或实现抽象成员

巫晋鹏
2023-03-14

我为我的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库。

我在对象(第2行)上收到一个错误,它说:

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

我真的是静态编程语言的新手,我在SO上也找不到任何解决方案。

非常感谢您的帮助。

编辑:

这是我的项目ClickSupport。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
        }
    }
}

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

共有2个答案

乜栋
2023-03-14

尝试一下:

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

    })
萧英光
2023-03-14

您的接口和方法签名不匹配。您的接口将一个函数声明为:

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

您将其覆盖为:

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

这些不是相同的方法签名。

如果这是一个Java接口,您可以在更改可空性时重写,因为不清楚可空性是什么(Java代码中没有注释)。但由于您将其移植到Kotlin接口,因此必须使用相同的精确签名进行重写。而是让这两个<代码>回收视图 和查看 可空,这会导致与原始签名不匹配。将重写函数更改为:

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

由于这是一个Kotin接口,因此无法使用SAM转换为Lambda,因此之前提供的其他答案无法工作。如果这是一个Java接口,您可以这样做。您可以跟踪KT-7770中Kotlin接口的SAM转换。

如果您希望此代码更加习惯于Kotlin,那么您需要函数引用或lambda而不是接口,并且您应该这样做,而不是依赖SAM转换。您可以在高阶函数和lambda中了解更多信息。这超出了您的问题范围,无法进行更详细的讨论。

 类似资料:
  • 问题内容: 这是我的代码,假设可以在按下按钮时更改一些文本:- 用下划线标记,它给我一个错误“类必须声明为抽象或实现抽象方法”。该代码大部分是从互联网上复制的,并且可以正常工作。可能仅是Android Studio错误。我如何使它工作? 问题答案: 必须实现该函数,否则您的类应该是抽象的,以便可以在某些子类中实现您的函数。但是在您的情况下,您犯了一个拼写错误。应该代替;

  • 我刚刚开始使用抽象类,重写val和singeltons。但是,我刚刚遇到了一个非常奇怪的行为。我的目标是拥有一个抽象类,然后创建几个扩展该抽象类的singeltons。因为我需要某些变量,所以我创建了抽象val,然后可以在子类中覆盖它(而不是通过构造函数传递它们)。 所以我上了4节课: 主要活动: 实例: 对象 AClass: 输出: 在此之后,我意识到被覆盖可能直到执行 之后才会初始化。但后来我

  • 介绍 我经常遇到这样一种情况,即库是用特定的编程语言编写的。这很好,如果我想用同一种语言使用这个库,但如果我想用另一种语言,那将是一个问题(这并不意味着可能会有或多或少的黑客方式) 对于一些库,我感觉它们是用特定的编程语言编写的,这仅仅是因为任何语言都可以(而且是因为作者个人的偏好),这意味着没有使用特定于语言的高级外部第三方库。对于这些情况,我认为如果有一种抽象(编程)语言,库作者可以用它来指定

  • 本文向大家介绍抽象类必须要有抽象方法吗?相关面试题,主要包含被问及抽象类必须要有抽象方法吗?时的应答技巧和注意事项,需要的朋友参考一下 不需要,抽象类不一定非要有抽象方法;但是包含一个抽象方法的类一定是抽象类。 示例代码: 上面代码,抽象类并没有抽象方法但完全可以正常运行。

  • 我试图从中的访问,将其放入查询中。我到处都在搜索如何访问它,但到目前为止我什么也没找到。我将非常感谢您的帮助:) 这里有一段代码:

  • 假设我有这门课: 以及子类: 我知道这是不可能的,但我想你明白我想要什么。如果Foobar实现了Cloneable,并且没有扩展AbstractFoo,那么子类就可以工作。我想我想要但不允许的是: 如果Foobar实现了Cloneable,并且没有扩展AbstractFoo,那么子类就可以工作。 除了扩展的抽象类,我怎么能做到“相同”?