Вы можете сделать это, взяв конструктор ViewHolder вместо класса. Таким образом, вам не придется использовать отражение для создания экземпляра ViewHolder. Для ViewHolder должен быть тип generic c, чтобы ваши подклассы могли правильно реализовать onBindViewHolder
и иметь доступ к указанному типу c ViewHolder.
Кроме того, вы должны задать свойству items
тип, иначе вы не сможете его использовать. И ваш подкласс, вероятно, должен иметь доступ к нему, поэтому он должен быть защищен, а не закрытым.
Я не проверял это:
abstract class AbstractListAdapter<VH: RecyclerView.ViewHolder> (
protected val items: List<*>,
private val layoutId: Int,
private val viewHolderConstructor: (View) -> VH >
) : RecyclerView.Adapter<VH>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(layoutId, parent, false)
return viewHolderConstructor(v)
}
//...
}
Затем для его реализации вы указываете конструктор ViewHolder в вызове суперконструктора, и вы указываете тип. Поскольку тип указан, вам не нужен параметр конструктора для него в подклассе.
class ListAdapter(private items: List<Files>, private val id: Int) : AbstractListAdapter<FileViewHolder>(items, id, ::FileViewHolder) {
override fun onBindViewHolder(holder: FileViewHolder, position: Int) {
//...
}
}
Тем не менее, я не уверен, чего это на самом деле достигает для вас. Это просто похоже на перемещение кода. Вам все равно придется извлечь ссылки на представление из родительского представления. Вы просто должны сделать это в инициализации ViewHolder, а не в onCreateViewHolder
. И теперь вам нужно быть осторожным, чтобы передать правильный макет, который соответствует указанному типу c ViewHolder. Вы также можете удалить этот параметр и выполнить макет в конструкторе ViewHolder, чтобы избежать этой проблемы. Но теперь все, что вы сделали, это переместили функциональность onCreateViewHolder
в блок init
вашего ViewHolder.
Кроме того, ваша версия абстрактного класса подрывает ожидаемые результаты переопределенных функций. Почему каждый элемент в списке имеет свой тип? Почему идентификаторы товара основаны на позиции в списке? Это только портит функциональность для редактирования данных списка (перестановка, добавление и удаление будут нарушены).