Создать класс BaseView в Kotlin - PullRequest
0 голосов
/ 18 февраля 2019

Я создаю класс BaseView в Kotlin, который будет расширяться всеми моими дочерними представлениями.

Моя проблема заключается в раздувании макета в классе BaseView, поскольку идентификатор ресурса макета предоставляется конструктору BaseView слишком поздно.

Вот мой BaseView

 abstract class BaseView @JvmOverloads constructor(
    context: Context?,
    attributeSet: AttributeSet? = null,
    defStyleAttr: Int = 0
) : MaterialCardView(context, attributeSet, defStyleAttr) {

    protected abstract val viewResourceId: Int
    protected abstract val needsRefresh: Boolean

    init {

        View.inflate(context,viewResourceId, this) // viewResourceId is not initialized here as yet
    }


    enum class State {
        DISABLED,
        LOADING,
        DONE,
        FAILED
    }
}

Проблема заключается в хорошо известном "доступе к неконечному свойству в конструкторе".Ранее я применял точно такую ​​же стратегию в Java, и это работало.

Как бы я поступил в этой ситуации?,Мне нужно раздуть мой макет в базе.Это имеет смысл, потому что инфляция является обычной операцией.

Является ли делегированное имущество подходящим способом?

РЕДАКТИРОВАТЬ: Так выглядит мой клиент

class StudentView @JvmOverloads constructor(
    context: Context?,
    attributeSet: AttributeSet? = null,
    defStyleAttr: Int = 0
) : BaseRegion(context, attributeSet, defStyleAttr) {
    override val viewResourceId=R.layout.student_view
    override val needsRefresh=false

    init {
        context?.
            let {  setCardBackgroundColor(ContextCompat.getColorStateList(context,R.color.colorAccent)!!)}

    }
}

1 Ответ

0 голосов
/ 18 февраля 2019

Это не будет работать, когда вы используете свойство с вспомогательным полем, поскольку инициализация этого поля происходит в конструкторе дочернего класса, который запускается после конструктора родителя.

Вы можететем не менее, используйте вычисляемое свойство, которое будет оцениваться при вызове его родителем, как и ожидалось:

override val viewResourceId: Int
    get() = R.layout.some_layout

Или вы можете определить абстрактную функцию и переопределить ее, что по сути будет то же самое:

override fun getViewResourceId(): Int = R.layout.some_layout

С другой стороны, использование @JvmOverloads может быть проблемой в определенных пользовательских представлениях, так как вызов любого из конструкторов, сгенерированных для вашего собственного класса, сначала делегирует в конструктор all-params внутрикласс, а затем вызвать конструктор всех параметров супер, вместо того чтобы каждый конструктор вызывал метод супер с соответствующим количеством параметров.Подробнее см. в этой статье (например).

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