我有一个抽象类:
abstract class AbstractViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
还有几个孩子:
class LabelViewHolder(itemView: View) : AbstractViewHolder(itemView) {
val name: TextView = itemView.label
}
class ButtonViewHolder(itemView: View) : AbstractViewHolder(itemView) {
val name: TextView = itemView.button
}
在onCreateViewHolder()
中,我想绕过when
的所有ViewType:
return when (viewType) {
ViewType.LABEL.id -> {
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.row_label, viewGroup, false)
LabelViewHolder(view)
}
ViewType.BUTTON.id -> {
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.row_button, viewGroup, false)
ButtonViewHolder(view)
}
为了不对许多when
分支写相同的内容,我想使用如下函数:
return when (viewType) {
ViewType.LABEL.id -> getNewViewHolder(viewGroup, R.layout.row_label, LabelViewHolder::class.java)
ViewType.BUTTON.id -> getNewViewHolder(viewGroup, R.layout.row_button, ButtonViewHolder::class.java)
}
private fun getNewViewHolder(viewGroup: ViewGroup, @LayoutRes layoutRes: Int, cls: Class<out AbstractViewHolder>): AbstractViewHolder {
val view = LayoutInflater.from(viewGroup.context).inflate(layoutRes, viewGroup, false)
return cls.newInstance() // cls(view) is not allowed.
}
如您所见,我无法返回AbstractViewHolder子对象,因为它不允许我创建带有参数view
的类。是否可以将类传递给函数并创建其对象?
答案 0 :(得分:1)
使函数具有通用化的参数化参数。像这样:
private inline fun <reified T> create(parent: ViewGroup, @LayoutRes layoutRes: Int): T {
return T::class.java.constructors[0].newInstance(
LayoutInflater.from(parent.context).inflate(layoutRes, parent, false)
) as T
}
然后
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AbstractViewHolder {
return when (viewType) {
0 -> create<LabelViewHolder>(parent, R.layout.abc_search_view)
else -> create<ButtonViewHolder>(parent, R.layout.abc_action_menu_item_layout)
}
}
现在,您可以访问T java对象并调用propert构造器。 这应该在调试中起作用,要发布,请记住要确保proguard不会删除您使用的构造函数。
答案 1 :(得分:0)
请参见https://stackoverflow.com/a/63690450/2914140。
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): AbstractViewHolder {
return when (viewType) {
LABEL -> createItem(viewGroup, R.layout.row_label, ::LabelViewHolder)
BUTTON -> createItem(viewGroup, R.layout.row_button, ::ButtonViewHolder)
else -> throw IllegalStateException("Wrong class")
}
}
private fun <T> createItem(
viewGroup: ViewGroup,
layoutRes: Int,
method: (View) -> T
): T {
val view = LayoutInflater.from(viewGroup.context).inflate(layoutRes, viewGroup, false)
return method(view) // Creates T(view).
}