【问题标题】:How to create a generic RecyclerView.Adapter with Kotlin如何使用 Kotlin 创建通用 RecyclerView.Adapter
【发布时间】:2019-12-16 17:01:55
【问题描述】:

我创建了一个扩展 RecyclerView.Adapter 的 Java 类。它是通用的,可以接受任何 SwipeableViewHolder 类型的 RecyclerView.ViewHolder 类:这是它的定义方式:

public abstract class SwipeableAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> {

     @Override
    public void onBindViewHolder(T holder, int position) {
        SwipeableViewHolder viewHolder = (SwipeableViewHolder) holder;

        ...
     }

}

这一切都很好。但是,当我尝试将其转换为 Kotlin 时,在 onBindViewHolder 函数中出现错误:

abstract class SwipeableAdapter<T : RecyclerView.ViewHolder>(protected var mContext: Context) :
        RecyclerView.Adapter<T>() {    

    override fun onBindViewHolder(holder: T, position: Int) {

            val viewHolder = holder as SwipeableViewHolder

            ...
    }

}

这里是 SwipeableViewHolder 类

open inner class SwipeableViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        @BindView(R.id.text_roll) internal var text_1: TextView? = null
        @BindView(R.id.text_trade) internal var text_2: TextView? = null
        @BindView(R.id.text_delete) internal var text_2: TextView? = null

        init {
            ButterKnife.bind(this, itemView)
        }
    }

当我尝试将持有人转换为 SwipeableViewHolder 时出现错误。错误是:“需要一个类型参数。如果您不想传递类型参数,请使用 SwipeableViewHolder”

我尝试了很多不同的方法来实现这一点,但似乎无法弄清楚。

Android Studio 版本:3.5.3 KOtlin 插件编译器:1.3

【问题讨论】:

  • 你说它可以接受任何类型的 ViewHolder,但是如果你传递任何不是 SwipeableViewHolder 的东西,它不会抛出 ClassCastException 吗?
  • @Tenfour04 。是的,你是对的。它可以接受任何 SwipeableViewHolder 类型的 RecyclerView.ViewHolder 类。我已经更新了我的帖子

标签: android generics kotlin android-recyclerview


【解决方案1】:

因为SwipeableViewHolderSwipeableAdapterinner 类(需要一个类型参数),所以您必须指定SwipeableAdapter 的类型参数是您的演员阵容的一部分:

val viewHolder = holder as SwipeableAdapter<*>.SwipeableViewHolder

【讨论】:

  • 不,您会认为这是基于抛出的错误。我添加了上面的 SwipeableViewHolder 以供参考
  • 我将您的代码复制并粘贴到我的 IDE 中,但无法重现此问题。 SwipeableViewHolder 嵌套在哪个类中? SwipeableAdapter 是否也在该类中定义?我必须让演员阵容合格(比如FooActivity.SwipeableViewHolder);你有类似的吗?
  • .SwipeableViewHolder 在 SwipeableAdapter 内部
  • Ben P,您对演员阵容资格的评论使我朝着正确的方向前进。它应该是:val viewHolder = holder as SwipeableAdapter.SwipeableViewHolder。谢谢。
【解决方案2】:

由于它只处理 SwipeableViewHolder 类型的 ViewHolders,您应该更改泛型类型绑定。那么你甚至不需要投射。

abstract class SwipeableAdapter<T : SwipeableViewHolder>(protected var mContext: Context) :
        RecyclerView.Adapter<T>() {    

    override fun onBindViewHolder(holder: T, position: Int) {

            // just use holder since it is already known to be a SwipeableViewHolder
    }

}

【讨论】:

    猜你喜欢
    • 2019-08-19
    • 2022-01-16
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    相关资源
    最近更新 更多