You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中创建具体化(reified)类型的RecyclerView.ViewHolder对象?

How to Instantiate a Generic RecyclerView.ViewHolder Subclass in Your Extension Function

Great question! You’re already on the right track using reified generics—this lets us access the actual type of T at compile time, which is key to solving this problem. Here’s how to properly create and return an instance of your ViewHolder subclass:

Most custom RecyclerView.ViewHolder implementations follow the standard pattern of having a primary constructor that takes a View (since RecyclerView.ViewHolder itself requires this). With reified generics, you can directly call this constructor:

inline fun <reified T : RecyclerView.ViewHolder> ViewGroup.createViewHolder(@LayoutRes res: Int): T {
    val inflater = LayoutInflater.from(context)
    val itemView = inflater.inflate(res, this, false)
    // Directly invoke the ViewHolder's constructor with the inflated view
    return T(itemView)
}

Key Details:

  • This approach is type-safe: The compiler will throw an error if your T subclass doesn’t have a primary constructor accepting a single View parameter.
  • There’s no runtime reflection overhead, so it’s performant for RecyclerView’s fast scrolling needs.

Solution 2: Reflection-Based Approach (For Edge Cases)

If you need to support ViewHolders with non-primary constructors (a rare scenario), you can use reflection to instantiate the class. Note that this adds runtime overhead and requires exception handling:

inline fun <reified T : RecyclerView.ViewHolder> ViewGroup.createViewHolder(@LayoutRes res: Int): T {
    val inflater = LayoutInflater.from(context)
    val itemView = inflater.inflate(res, this, false)
    
    return try {
        // Look up and invoke the constructor that takes a View parameter
        T::class.java.getConstructor(View::class.java).newInstance(itemView)
    } catch (e: NoSuchMethodException) {
        throw IllegalArgumentException("Your ViewHolder must have a constructor that accepts a single View parameter", e)
    } catch (e: IllegalAccessException) {
        throw RuntimeException("Could not access the ViewHolder constructor", e)
    } catch (e: InstantiationException) {
        throw RuntimeException("Could not instantiate the ViewHolder", e)
    }
}

Example Usage

Suppose you have a standard ViewHolder like this:

class MyItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    // Add your view bindings or logic here
}

You can use the extension function in your adapter’s onCreateViewHolder method:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyItemViewHolder {
    return parent.createViewHolder<MyItemViewHolder>(R.layout.item_my)
}

内容的提问来源于stack exchange,提问作者Samuel Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:07:35