¿Cuál es la mejor manera de declarar en el componente UI en Android con Kotlin?

Intento crear una aplicación para Android usando Kotlin por primera vez.

Quiero declarar en algunos botones fuera del método OnCreate y solo puedo inicializarlos dentro de esta function con findViewById.

¿Puedo declarar en código simple y limpio como en Java?

private Button btnProceed; 

Porque al convertirlo en Kotlin se ve así:

 private var btnProceed: Button? = null 

Y luego, cuando se inicialice la function OnClick, ¡hay que agregar! firmar:

 btnProceed!!.setOnClickListener 

¿Cuál es la forma correcta y más limpia?

Este es un buen caso de uso para lateinit . Marcar una propiedad lateinit permite hacer que no se pueda lateinit , pero no asignarle un valor en el momento en que se llama al constructor de su Actividad. Está allí precisamente para classs como Actividades, cuando la initialization ocurre en un método de initialization separado, más tarde que el constructor que se está ejecutando (en este caso, onCreate ).

 private lateinit var btnProceed: Button 

Si la propiedad se lee antes de que se le asigne un valor real, arrojará una exception en time de ejecución: al usar lateinit , se está tomando la responsabilidad de inicializarla antes de acceder a ella por primera vez.


De lo contrario, si quiere que el comstackdor le garantice un acceso seguro, puede hacer que el Button nulo como lo hace el convertidor de forma pnetworkingeterminada. En lugar de lo inseguro !! Sin embargo, el operador , que el convertidor suele utilizar, debe utilizar el operador de llamada segura al que accede a la propiedad:

 btnProceed?.setOnClickListener { ... } 

Esto hará una llamada regular si btnProceed es un valor no nulo, y no hace nada de lo contrario.


Como nota final, puedes echar un vistazo a las extensiones de Kotlin para Android , lo que elimina la necesidad de crear properties para tu View set, si funciona para tu proyecto.


Última edición (por ahora): también debe considerar usar lazy como se describe en las other answers . Ser perezoso es genial.

En lugar de usar lateinit , también puede hacer una initialization lateinit :

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

La primera vez que acceda a la propiedad del button , ejecutará el bloque una vez y usará el resultado para futuras llamadas. En onCreate por ejemplo, ahora puedes acceder directamente a él:

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

Puedes hacerlo con lateinit como @ zsmb13, pero esto tiene la desventaja de que tus vistas serán variables en lugar de finales. Si quieres que sean definitivos, puedes usar la delegación de properties lazy

Al usar lazy puede declarar cómo se inicializará el valor cuando intente acceder a él por primera vez, declarando

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

Cada vez que acceda a su btnProceed tendrá su actividad (este ejemplo supone que está utilizando una actividad) cargada para que pueda usar ese método

  • Evite otra pausa de la aplicación de audio en YouTubePlayerFragment init
  • Crear una instancia de un oyente de interfaz en Kotlin
  • Generar class de datos con KotlinPoet
  • Delegar propiedad a otra propiedad
  • ¿Cómo se configuran las properties extras de Gradle en el Kotlin DSL?
  • Android: obteniendo IllegalAccessError solo en APK incorporados
  • Reaccionar a la llamada de actualización
  • Ingrese los valores propios para combinarlos
  • JOOQ selecciona la expresión
  • Cómo devolver una interfaz como javawith Kotlin
  • ¿Cómo agregar una class Kotlin en un proyecto de Android Studio?