Kotlin Native UI

BosLeo
4 min readDec 16, 2020

--

Ever wonder how it would be if you only have to learn one language that does it all that is needed to develop a software. You will master it right?

Well, it seems we will be able to do it in near future with Kotlin Programming Language.

Since we are talking about UI here let me brief you about “Declarative UI”. The code we write describes the UI we want, but not how to transition into that state. The critical thing here is that when writing declarative code, you no longer need to worry about what the previous state of your UI was in, you only need to specify what your current state should be. The framework controls how to get from one state to the other, so we no longer need to think about it.

Following this paradigm, Google and JetBrains are the two major companies who are developing UI Toolkits which are built around Kotlin. Google Android Jetpack Team is developing Jetpack Compose and JetBrains in collaboration with Google Android Jetpack Team are developing Compose for Desktop. In this blog, we will focus on Jetpack Compose. Both Compose for Desktop and Jetpack Compose share common code. Compose for Desktop is built on top this common code so principles will remain the same.

Jetpack Compose

A modern UI toolkit designed to help you quickly and easily build beautiful apps across all Android platforms.

Why the need?

An Android view hierarchy has been representable as a tree of UI widgets. To update the UI, you need to walk the tree using functions like “findViewById ()” or use view binding, data binding etc. and manually manipulate view by calling properties like “textView.setOnClickListener ()”. This increases the chances of human errors. These errors can be minimized if a declarative approach is referred to. Jetpack Compose just does that using Kotlin.

Source: https://developer.android.com/jetpack/compose/mental-model

In Compose you must define a composable function and describe your View inside it. Pass the data as the method’s argument on which this widget will behave.

Less code — No classes involved. You have a method, and it has parameters as data for that UI.

Intuitive — Describe your UI and its states. Give it data and then just let composable function do its job. It will manage states according to data.

Powerful — All android platform APIs are currently working on giving support to Compose so when it is stable you can use it with existing projects out of the box.

Kotlin Benefits

Default values for function arguments

Say you have a function called Polygon with parameters like no. of sides, thickness, edge colour etc. In other languages, you might expect to write several functions or use function overloading but with Kotlin you just have to write a single function and give its parameters a default value so that if the caller doesn’t explicitly pass those values, default values are consumed. Also, with Kotlin you can give named parameters which are more readable when you call a function with just a few parameters.

E.g.

fun drawSquare(side: Int = 3, thickness: Int = 2 edgeColor: Color = Color.Black) { … }drawPolygon(side = 30, thickness = 5, edgeColor = Color.Red)

Higher-order functions and lambda expressions

Kotlin supports higher-order functions, functions that receive other functions as parameters. If there is a fixed behaviour that a UI needs to do on user action you can define it in your composable function as Higher-order function.

E.g.

Button (…
onClick = {// do something
}
)

Kotlin offers a special syntax for calling higher-order functions whose last parameter is a lambda. It is called Trailing Lambda Syntax. Here you don’t need to specify the last parameter in function brackets instead define it in parenthesis after function brackets.

E.g.

Row {Text (“Some text”)
Text (“Some more text”)
}

Here Row is a composable function with a trailing lambda of children

Scopes and Receivers

Scopes and Receivers let you offer controlled functionality to or from its children when there is a complex UI. Some methods and properties are only available in a certain scope. Some APIs accept lambdas which are called in receiver scope. Those lambdas have access to properties and functions that are defined elsewhere.

Delegated Properties

Kotlin offers “by” keyword to define delegated properties. These properties are called as if they were fields, but their value is determined dynamically by evaluating an expression.

E.g.

var showDialog by remember {mutableStateOf(false)}
// Updating the var automatically triggers a state change
showDialog = true

Final Thoughts

Since Compose is backed by two big tech Giants Google and JetBrains, reliability for support is high. They are also working on Kotlin Multiplatform with the intention that developers only have to write business logic once and then use it in native development environments be it Android, iOS, Web or Desktop. Currently, all these are in alpha stage. You can check out more about Jetpack Compose on this link.

--

--