Передайте класс функции Kotlin для создания ViewHolder в адаптере - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть абстрактный класс:

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() Я хочу обойти все ViewTypes с помощью when:

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. Можно ли передать класс функции и создать ее объект?

1 Ответ

1 голос
/ 01 апреля 2019

Создать функцию с обобщенным параметром. Как это:

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 и вызвать его свойства consturctor. Это должно работать при отладке, для выпуска не забудьте убедиться, что proguard не удалит используемый вами конструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...