Kotlin добавление поля val в подкласс с несколькими конструкторами - PullRequest
3 голосов
/ 29 мая 2020

Я создаю настраиваемое представление в Android и хочу добавить поле val в конструктор, однако представление содержит несколько конструкторов.

class CustomView : View {

    // I want a `val field: CustomField` in my constructor

    constructor(
        context: Context
    ) : super(context)

    constructor(
        context: Context,
        attrs: AttributeSet? = null
    ) : super(context, attrs)

    constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyle: Int = 0
    ) : super(context, attrs, defStyle)

    ...
}

Kotlin не допускает поля val в вторичные конструкторы, поэтому я не могу сделать что-то вроде этого:

class CustomView : View {

    constructor(
        val field: CustomField,
        context: Context
    ) : super(context)

    constructor(
        val field: CustomField,
        context: Context,
        attrs: AttributeSet? = null
    ) : super(context, attrs)

    constructor(
        val field: CustomField,
        context: Context,
        attrs: AttributeSet? = null,
        defStyle: Int = 0
    ) : super(context, attrs, defStyle)

    ...

Как я могу добавить поле val к ​​конструкторам, но при этом расширить несколько конструкторов родительского класса?

  • I Я пробовал добавить val во вторичные конструкторы, но Kotlin не позволяет использовать val во вторичном конструкторе.
  • Я пробовал создать один первичный конструктор (тот, который я планирую явно использовать ) и игнорируя другие. Затем Android Studio выдает предупреждение Lint о том, что мне не хватает конструкторов. (и я хотел бы знать, есть ли способ реализовать их все в любом случае)
  • Я пробовал добавить поле, которое я хочу, в качестве другого параметра во вторичный конструктор (не val) и установить его во вторичном конструкторе тело конструктора. Это приводит к тому, что компилятор жалуется, что val не инициализируется, если я пытаюсь получить доступ в блоке инициализации, а затем ЛИНТЕР все еще жалуется, что я не реализую конструкторы super
class CustomView : View {

    val field: CustomField

    constructor(
        field: CustomField,
        context: Context
    ) : super(context) { this.field = field }

    ...
  • Если val, который мне нужен, является примитивным типом, я мог бы передать его как часть набора атрибутов View, однако в данном случае это не так. Также я надеюсь на общее решение Kotlin, если оно существует.

1 Ответ

2 голосов
/ 29 мая 2020

Вы можете сделать это таким образом.

Вы получите ошибку Property must be initialized or be abstract, потому что поле myCustomField должно быть инициализировано в каждом конструкторе вашего класса.

Также вы не можете использовать ключевое слово val в параметрах

    class CustomView : View {

        val myCustomField : CustomField

        constructor(customField : CustomField, context: Context?) : super(context){
            this.myCustomField = customField
        }

        constructor(customField : CustomField ,context: Context?, attrs: AttributeSet?) : super(context, attrs){
            this.myCustomField = customField

        }
        constructor(customField : CustomField, context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
            context,
            attrs,
            defStyleAttr
        ){
            this.myCustomField = customField
        }

        constructor(
            customField : CustomField,
            context: Context?,
            attrs: AttributeSet?,
            defStyleAttr: Int,
            defStyleRes: Int
        ) : super(context, attrs, defStyleAttr, defStyleRes){
            this.myCustomField = customField
        }
    } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...