· 4 min read
Custom Views in Android with Kotlin (KAD 06)
class KotlinView : View {
}
Cuando vimos el artículo sobre clases, puede que recuerdes que en general solo se usa un constructor. Este es un problema para crear custom views.
El marco de Android espera tener varios constructores disponibles según dónde y cómo se esté creando la vista (por código, usando XML, si se establece un tema…), así que no podemos ignorar este caso.
Para esto, el equipo de Kotlin proporcionó la posibilidad de tener varios constructores en la misma clase, solo para casos como este.
La compatibilidad con Java es un requisito esencial para Kotlin, así que cada vez que te sientas bloqueado, piensa que debe haber alguna manera de lograr lo que necesitas.
Crear una vista personalizada en Kotlin
Incluso si ya tienes experiencia creando vistas personalizadas y algo de conocimiento de Kotlin, es posible que la primera vez que crees una vista personalizada en Kotlin, lo encuentres un poco complicado.
Implementar varios constructores es una de las cosas más complejas en Kotlin, precisamente porque es un caso de uso raro.
Pero no te preocupes, una vez que lo hayas visto una vez, el resto son muy similares.
Note: este artículo sigue siendo válido para entender cómo usar múltiples constructores en una clase de Kotlin, pero como Kirill Rakhman menciona en los comentarios, hay una mejor manera. Lee hasta el final.
Crear una clase que extiende View
Para hacer esto, crea una clase como vimos antes. Haz que extienda de View, por ejemplo, pero no indiques ningún constructor:
class KotlinView : View {
}
Verás que este código no compila, porque requiere llamar al constructor de la clase padre.
Si sabes que solo estás inflando tu vista desde código Kotlin, por ejemplo, podrías usar la forma de constructor único que ya vimos:
class KotlinView(context: Context?) : View(context) {
}
Pero ten cuidado, porque si alguien decide agregar esta vista a un XML, fallará.
Spoiler: ¿Ves ese signo de interrogación justo después de Context? En Kotlin, si queremos que una variable o parámetro sea nulo, tenemos que especificarlo explícitamente usando un signo de interrogación. Luego el compilador nos obligará a comprobar que no es nulo antes de hacer nada con él. Lo veremos en próximos artículos.
Implementar los múltiples constructores
Los constructores utilizan la palabra reservada constructor
, y necesitan definir en su declaración qué constructor llaman. Puede ser otro constructor de la misma clase (usando this
) o el de la clase padre (usando super
).
Así es como defines los constructores para una vista de Android:
class KotlinView : View {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
...
}
}
Una implementación más fácil
La alternativa que Kirill menciona en los comentarios (¡gracias por eso!) es mucho más simple y fácil de leer. Se basa en asignar valores predeterminados para los argumentos del constructor, pero necesita un pequeño ajuste.
El asunto es que cuando creas un constructor (o cualquier función) con valores predeterminados para algunos argumentos, el bytecode generado solo permite usar esos valores predeterminados en Kotlin. Si usas ese constructor en Java, te verás obligado a especificar un valor para todos los argumentos.
Eso es porque Java no tiene esta característica del lenguaje. En Java, normalmente lo resolverías generando sobrecargas de función con todas las variaciones que necesites.
Puedes obtener este código generado automáticamente utilizando la anotación @JvmOverloads
en Kotlin.
El código sería así:
class KotlinView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)
Conclusión
Una vez que lo ves, no es tan complicado generar tus vistas personalizadas gracias a la existencia de múltiples constructores, e incluso mucho más fácil utilizando la anotación @JvmOverloads
.
Esto puede ser útil para cualquier clase donde necesites más de un constructor. Pero en general, como puedes asignar valores predeterminados a los parámetros (y así evitar sobrecargas), no es tan común necesitar más de uno.
¿Todavía no estás convencido sobre Kotlin para Android? ¡Empieza a usarlo tan pronto como sea posible! Gracias a los artículos anteriores puedes aprender más sobre Kotlin, o te recomiendo que te inscribas en mi formación gratuita aquí.