Каков наилучший способ объявить компонент UI в Android с Kotlin?

Я пытаюсь создать приложение Android с помощью Kotlin в первый раз.

Я хочу объявить на некоторых кнопках вне метода OnCreate, и я могу инициализировать их только внутри этой функции с помощью findViewById.

Могу ли я объявить простой и чистый код, например, в java?

private Button btnProceed; 

Потому что, преобразовывая его в Kotlin, он выглядит так:

 private var btnProceed: Button? = null 

И тогда при инициализации функции OnClick необходимо добавить! знак:

 btnProceed!!.setOnClickListener 

Каков правильный и самый чистый способ?

Это хороший прецедент для lateinit . Маркировка свойства lateinit позволяет сделать его недействительным, но не назначать ему значение в то время, когда вызывается конструктор Activity. Он существует именно для таких классов, как «Деятельности», когда инициализация происходит в отдельном методе инициализации, позже запускаемого конструктора (в данном случае onCreate ).

 private lateinit var btnProceed: Button 

Если свойство читается до того, как ему присвоено действительное значение, оно будет генерировать исключение во время выполнения – используя lateinit , вы берете на себя ответственность за его инициализацию перед тем, как получить доступ к ней в первый раз.


В противном случае, если вы хотите, чтобы компилятор гарантировал вам безопасный доступ, вы можете сделать Button нулевым, как это делает конвертер по умолчанию. Вместо небезопасных !! оператор , который часто использует конвертер, вы должны использовать оператора безопасного вызова, где вы получаете доступ к свойству:

 btnProceed?.setOnClickListener { ... } 

Это приведет к регулярному вызову, если btnProceed является ненулевым значением и ничего не делает.


Наконец, вы можете проверить Kotlin Android Extensions , что устраняет необходимость создания свойств для вашего View целом, если оно работает для вашего проекта.


Последнее редактирование (на данный момент): вы также должны смотреть на использование lazy как описано в other answers . Быть ленивым – это круто.

Вместо использования lateinit вы также можете выполнять ленивую инициализацию :

 private val button by lazy { findViewById(R.id.button) as Button } 

При первом доступе к свойству button он будет выполнять блок один раз и использовать результат для будущих вызовов. Например, в onCreate вы можете напрямую получить к нему доступ:

 fun onCreate(savedInstanceState: Bundle?) { super.onCreate(bundle) setContentView(R.layout.my_view) button.setOnClickListener { ... } } 

Вы можете сделать это с помощью lateinit поскольку @ zsmb13 предлагает, НО это имеет тот недостаток, что ваши представления будут переменными, а не окончательными. Если вы хотите, чтобы они были окончательными, вы можете использовать lazy делегацию собственности

Используя lazy вы можете объявить, как значение будет инициализировано при первом попытке получить к нему доступ, объявив

 private val btnProceed: Button by lazy { findViewById(R.id.yourID) } 

Всякий раз, когда вы btnProceed доступ к btnProceed вы будете btnProceed свою активность (этот пример предполагает, что вы используете активность), чтобы вы могли использовать этот метод

  • Сбор данных из разных снимков в FirebaseAdapter
  • Почему метод ByteBuffer putShort (значение) работает неправильно в моем случае?
  • Плагин Anko не может работать в версии Androidstudio> 2.1
  • Kotlin Anko Custom View Родительский охват
  • Подстановочные знаки, общие для Kotlin для параметра
  • андроид, получивший манифест слияния с ошибкой после обновления до новой версии gradle
  • Котлин объединяет два изменяемых значения с возможностью смены имени
  • Тема и стиль Анко
  • Как обходить NetworkOnMainThreadException на Kotlin
  • NullPointerException для android.support.v4.app.NotificationCompatBase $ Action.getIcon ()
  • Как установить стоимость недвижимости в Котлине
  • Interesting Posts

    Как определить собственные свойства для моделей на основе Йены?

    JNI: чтение и запись в прямом буфере

    Смутно о Null Safety в Котлине

    Как реорганизовать представление, чтобы разрешить фильтрацию элементов, привязанных к наблюдаемомуArrayList, внутри приложения tornadofx

    Расширение Котлина для следующего значения Enum без отражения

    Класс <?> Clazz в Котлине

    firebase db: модели с переданными свойствами Котлина

    Как проверить функцию kotlin varargs с помощью mockito

    Двухмерный общий поставщик массивов

    Как указать поле в коробке может быть равно NULL в моем коде миграции Realm?

    Преобразование строки JSON в экземпляр класса данных в Spring

    Android Kotlin передает значение с текстовых полей на numberPicker

    Как реализовать ленивый адаптер recyclerView для загрузки, например realm recyclerView, используя kotlin

    Каков правильный способ использования расширений Anko Coroutines?

    Как запустить код, если объект имеет значение null?

    Давайте будем гением компьютера.