Kotlin
A concise multiplatform language developed by JetBrains
Announcing Anko for Android
We’re excited to announce a library we’ve been working on for Android development, which, among other things allows the creation of Application Interfaces in a type-safe and dynamic way using a DSL.
A Sample Taste
Here is a small example describing some of Anko’s possibilities. Imagine we need to create a simple sign-up form consisting of an EditText
for a username and a “Sign up” Button
. The code for this, using Anko would be:
import kotlinx.android.anko.* class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) verticalLayout { padding = dip(16) textView("Username:") { textSize = 18f }.layoutParams { verticalMargin = dip(4) } val login = editText() button("Sign up") { textSize = 20f onClick { login(login.text) } }.layoutParams { topMargin = dip(8) } } } }
Anko makes extensive use of Kotlin’s extension functions and properties arranged into type-safe builders to describe the user interface. In return, we get conciseness and type-safety at compile time.
Of course, we can also see a preview during design time using the Anko Preview plugin, available for both IntelliJ IDEA and Android Studio:
If we now want to add another text input widget, for instance an email, we could probably create another pair of textView()
and editText()
function calls. However, a nicer approach would be to extract the corresponding DSL fragment into a new function:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) verticalLayout { padding = dip(16) val login = inputField("Username") val email = inputField("E-mail") button("Sign up") { textSize = 20f onClick { login(login.text) } }.layoutParams { topMargin = dip(8) } } } fun _LinearLayout.inputField(name: String): TextView { textView("$name:") { textSize = 18f }.layoutParams { verticalMargin = dip(4) } return editText() }
Any additional inputs only require a single function call.
End result of the form would be:
Partially defined listeners
Anko is very helpful when you are using Android listeners with lots of methods. Consider the following code written that does not use Anko:
seekBar.setOnSeekBarChangeListener(object: OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { // Something } override fun onStartTrackingTouch(seekBar: SeekBar?) { // Just an empty method } override fun onStopTrackingTouch(seekBar: SeekBar) { // Another empty method } })
Here’s the version using Anko:
seekBar { onProgressChanged { (seekBar, progress, fromUser) -> // Something } }
Methods that have empty bodies no longer require, well, empty implementations. Also, if setting onProgressChanged()
and onStartTrackingTouch()
for the same View, these two “partially defined” listeners will be merged.
More than a DSL
Anko is not just a DSL but a library which facilitates Android development in different areas. It has many methods covering dialogs, asynchronous tasks, services, intents and even SQLite database access.
For instance, if you want to start a new Activity
:
// Without Anko val intent = Intent(this, javaClass<MyActivity>()) intent.putExtra("id", 5) startActivity(intent) // With Anko startActivity<MyActivity>("id" to 5)
Or activate vibrator:
// Without Anko val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator vibrator.vibrate(500) // With Anko vibrator.vibrate(500)
Or even send a toast message:
// Without Anko Toast.makeText(this, "Download is complete!", Toast.LENGTH_SHORT).show() // With Anko toast("Download is complete!")
Existing code support
You can keep your old classes written in Java. Moreover, if you still want (or have) to write a Kotlin activity class and inflate an XML layout for some reason, you can use View
properties and listener helpers which would make things easier:
name.hint = "Enter your name" name.onClick { /* do something */ }
Benefits of Anko
Hopefully you can see that Anko offers a series of benefits, in particular:
- Everything is in one place. Instead of splitting layouts into static (XML) and dynamic parts and then trying to tie them together, we can just write everything we want using Kotlin. Compile-time type checking is a sweet bonus.
- Anko can make our code more concise and readable.
- It allows for easy re-use. We can just extract a part of the DSL into a function and use it multiple times.
Give it a try!
Anko is still in alpha stage but we want to release early to get your feedback, so please give it a try. We’ve made it as simple as possible to do so. It’s all published on Maven Central, and if you’re using Gradle, you can easily add the required dependencies to the build.gradle
file:
dependencies { compile 'org.jetbrains.anko:anko:0.5-15' }
The Anko Preview plugin is available both for IntelliJ IDEA and Android Studio. You can download it directly from the Plugin Repository.
There are binaries targeting both raw Android (SDK version 15, Ice Cream Sandwich) and Android with a support-v4 package.
Also, last but not least, much like everything related to Kotlin, Anko is fully Open Source. The repository is on GitHub and as always, contributions are welcome!